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 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 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_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) {
const parts = repoUrl.split('/');
@ -267,6 +270,14 @@ async function processOpenOrEditAction() {
console.log('+ This PR fixes issues: #' + issues.join(', '));
} else {
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 = {};

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 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 {
constructor() {

View File

@ -7,14 +7,22 @@ export default class CreateEditViewPo extends ComponentPo {
return new NameNsDescription(this.self());
}
createButton() {
return new AsyncButtonPo(this.self().find('.cru-resource-footer .role-primary'));
}
create() {
return new AsyncButtonPo(this.self().find('.cru-resource-footer .role-primary')).click();
return this.createButton().click();
}
save() {
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() {
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';
export default class CruResourcePo extends ComponentPo {
findSubTypeByName(name: string) {
return this.self().find(`[data-testid="subtype-banner-item-${ name }"]`);
}
selectSubType(groupIndex: number, itemIndex: number) {
return this.self().find('.subtypes-container > div')
.eq(groupIndex).find('.item')
@ -17,6 +21,10 @@ export default class CruResourcePo extends ComponentPo {
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 {
cy.intercept(method, endpoint).as(endpoint);
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();
}
importYamlCancelClick() {
this.self().find('[data-testid="import-yaml-cancel"]').click();
}
importYamlSortableTable() {
return new SortableTablePo(this.self());
}

View File

@ -1,5 +1,4 @@
import ComponentPo from '@/cypress/e2e/po/components/component.po';
export default class LabeledSelectPo extends ComponentPo {
toggle() {
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
* @returns

View File

@ -13,4 +13,25 @@ export default class ResourceTablePo extends ComponentPo {
snapshotNowButton() {
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"]');
}
cancel(): Cypress.Chainable {
return this.self().find('button.role-secondary');
}
saveOrCreate(): AsyncButtonPo {
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');
}
/**
* 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)
*/

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 AsyncButtonPo from '@/cypress/e2e/po/components/async-button.po';
import CheckboxInputPo from '@/cypress/e2e/po/components/checkbox-input.po';
import { CypressChainable } from '@/cypress/e2e/po/po.types';
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 ) {
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);
}
saveCreateForm(): AsyncButtonPo {
return new AsyncButtonPo('[data-testid="form-save"]', this.self());
}
saveCreateWithErrorRetry(attempt = 1): Cypress.Chainable | null {
if (attempt > 3) {
return null;
@ -56,7 +51,8 @@ export default class MgmtUserEditPo extends PagePo {
cy.intercept('POST', 'v3/users').as('userCreation');
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
// main xhr request for user creation
@ -83,7 +79,8 @@ export default class MgmtUserEditPo extends PagePo {
saveAndWaitForRequests(method: string, url: any, multipleCalls?: boolean): CypressChainable {
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 }));
}

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 {
/**
* 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
*/
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
*/
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
*/
resourceYaml() {
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() {
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 {
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`;
}
@ -13,7 +13,7 @@ export default class StorageClassesCreateEditPo extends PagePo {
throw new Error('invalid');
}
constructor(clusterId = '_', id?: string) {
constructor(clusterId = 'local', id?: string) {
super(StorageClassesCreateEditPo.createPath(clusterId, id));
}

View File

@ -1,13 +1,13 @@
import PagePo from '@/cypress/e2e/po/pages/page.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 NameNsDescriptionPo from '@/cypress/e2e/po/components/name-ns-description.po';
import ResourceDetailPo from '@/cypress/e2e/po/edit/resource-detail.po';
import CodeMirrorPo from '~/cypress/e2e/po/components/code-mirror.po';
const installChartPage = new InstallChartPage();
const appsPage = new ChartInstalledAppsPagePo('local', 'apps');
const appsPage = new ChartInstalledAppsListPagePo('local', 'apps');
const root = '.dashboard-root';
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 LabeledInputPo from '@/cypress/e2e/po/components/labeled-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
*/
export default class ClusterManagerEditImportedPagePo extends PagePo {
private static createPath(clusterId: string, clusterName: string) {
return `/c/${ clusterId }/manager/provisioning.cattle.io.cluster/fleet-default/${ clusterName }`;
private static createPath(clusterId: string, ns: string, clusterName: string) {
return `/c/${ clusterId }/manager/provisioning.cattle.io.cluster/${ ns }/${ clusterName }`;
}
static goTo(clusterId: string, clusterName: string ): Cypress.Chainable<Cypress.AUTWindow> {
return super.goTo(ClusterManagerEditImportedPagePo.createPath(clusterId, clusterName));
static goTo(clusterId: string, ns: string, clusterName: string ): Cypress.Chainable<Cypress.AUTWindow> {
return super.goTo(ClusterManagerEditImportedPagePo.createPath(clusterId, ns, clusterName));
}
constructor(clusterId = '_', clusterName: string) {
super(ClusterManagerEditImportedPagePo.createPath(clusterId, clusterName));
constructor(clusterId = '_', ns = 'fleet-default', clusterName: string) {
super(ClusterManagerEditImportedPagePo.createPath(clusterId, ns, clusterName));
}
nameNsDescription() {
@ -37,6 +38,26 @@ export default class ClusterManagerEditImportedPagePo extends PagePo {
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() {
return new CheckboxInputPo('[data-testid="private-registry-enable-checkbox"]');
}
@ -56,4 +77,8 @@ export default class ClusterManagerEditImportedPagePo extends PagePo {
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() {
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());
}
cancelButton(): Cypress.Chainable {
return this.self().get('button.role-secondary');
}
doneButton(): AsyncButtonPo {
return new AsyncButtonPo('[data-testid="token_done_create_button"]', this.self());
}
@ -43,4 +47,8 @@ export default class CreateKeyPagePo extends PagePo {
create(): Cypress.Chainable {
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 { GetOptions } from '@/cypress/e2e/po/components/component.po';
import { SharedComponentsPo } from '@/cypress/e2e/po/components/shared-components/shared-components.po';
import { BaseListPagePo } from '@/cypress/e2e/po/pages/base/base-list-page.po';
import ResourceTablePo from '@/cypress/e2e/po/components/resource-table.po';
const terminal = new Kubectl();
/**
* 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') {
return `/c/${ clusterId }/${ product }/catalog.cattle.io.app`;
}
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') {
super(ChartInstalledAppsPagePo.createPath(clusterId, product));
super(ChartInstalledAppsListPagePo.createPath(clusterId, product));
}
filter(key: string) {
this.self().get('.input-sm.search-box').type(key);
}
sharedComponents(options?: GetOptions) {
return new SharedComponentsPo('[data-testid="installed-app-catalog-list"]', this.self(options));
appsList() {
return new ResourceTablePo('[data-testid="installed-app-catalog-list"]');
}
waitForInstallCloseTerminal(interceptName: string, installableParts: Array<String>) {
@ -37,7 +36,7 @@ export default class ChartInstalledAppsPagePo extends PagePo {
terminal.closeTerminal();
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

View File

@ -1,11 +1,11 @@
import PagePo from '@/cypress/e2e/po/pages/page.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 EventsListPo from '@/cypress/e2e/po/lists/events-list.po';
import TabbedPo from '@/cypress/e2e/po/components/tabbed.po';
import CertificatesPo from '@/cypress/e2e/po/components/certificates.po';
import { HeaderPo } from '@/cypress/e2e/po/components/header.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 {
private static createPath(clusterId: string) {
@ -38,10 +38,6 @@ export default class ClusterDashboardPagePo extends PagePo {
return new CustomBadgeDialogPo();
}
eventsList(): EventsListPo {
return new EventsListPo('[data-testid="sortable-table-list-container"]');
}
certificates(): CertificatesPo {
return new CertificatesPo();
}
@ -64,6 +60,14 @@ export default class ClusterDashboardPagePo extends PagePo {
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() {
return new HeaderPo();
}

View File

@ -1,4 +1,5 @@
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 {
private static createPath(clusterId: string) {
@ -13,6 +14,12 @@ export default class ClusterToolsPagePo extends PagePo {
super(ClusterToolsPagePo.createPath(clusterId));
}
static navTo() {
const sideNav = new ProductNavPo();
sideNav.navToSideMenuEntryByLabel('Tools');
}
featureChartCards(): Cypress.Chainable {
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 { 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) {
return `/c/${ clusterId }/explorer/event`;
}
static goTo(clusterId: string): Cypress.Chainable<Cypress.AUTWindow> {
return super.goTo(EventsPagePo.createPath(clusterId));
return super.goTo(EventsPageListPo.createPath(clusterId));
}
constructor(clusterId: string) {
super(EventsPagePo.createPath(clusterId));
super(EventsPageListPo.createPath(clusterId));
}
static navTo() {
@ -20,15 +20,20 @@ export class EventsPagePo extends PagePo {
sideNav.navToSideMenuEntryByLabel('Events');
}
}
eventslist(): EventsListPo {
return new EventsListPo('[data-testid="sortable-table-list-container"]');
export class EventsCreateEditPo extends BaseDetailPagePo {
private static createPath(clusterId: string, namespace?: string, eventName?: string) {
const root = `/c/${ clusterId }/explorer/event`;
return namespace && eventName ? `${ root }/${ namespace }/${ eventName }` : `${ root }/create`;
}
/**
* Convenience method
*/
sortableTable() {
return this.eventslist().resourceTable().sortableTable();
static goTo(path: string): Cypress.Chainable<Cypress.AUTWindow> {
throw new Error('invalid');
}
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 ResourceListMastheadPo from '@/cypress/e2e/po/components/ResourceList/resource-list-masthead.po';
import NameNsDescription from '@/cypress/e2e/po/components/name-ns-description.po';
import AsyncButtonPo from '@/cypress/e2e/po/components/async-button.po';
import GenericPrompt from '@/cypress/e2e/po/prompts/genericPrompt.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 default class ProjectNamespacePagePo extends PagePo {
export class ProjectsNamespacesListPagePo extends BaseListPagePo {
private static createPath(clusterId: string) {
return `/c/${ clusterId }/explorer/projectsnamespaces`;
}
static goTo(clusterId: string): Cypress.Chainable<Cypress.AUTWindow> {
return super.goTo(ProjectNamespacePagePo.createPath(clusterId));
return super.goTo(ProjectsNamespacesListPagePo.createPath(clusterId));
}
constructor(clusterId: string) {
super(ProjectNamespacePagePo.createPath(clusterId));
constructor(clusterId = 'local') {
super(ProjectsNamespacesListPagePo.createPath(clusterId));
}
flatListButton() {
return this.self().getId('button-group-child-0');
static navTo() {
const sideNav = new ProductNavPo();
sideNav.navToSideMenuEntryByLabel('Projects/Namespaces');
}
flatListClick(): Cypress.Chainable {
return this.flatListButton().click();
createNamespaceButton() {
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() {
return this.self().getId('create_project_namespaces');
static goTo(path: string): Cypress.Chainable<Cypress.AUTWindow> {
throw new Error('invalid');
}
createProjectNamespaceClick(): Cypress.Chainable {
return this.createProjectNamespaceButton().click();
}
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();
constructor(clusterId = 'local', projName?: string) {
super(ProjectCreateEditPagePo.createPath(clusterId, projName));
}
tabResourceQuotas() {
@ -65,10 +59,6 @@ export default class ProjectNamespacePagePo extends PagePo {
return new LabeledInputPo(cy.get('[data-testid="projectrow-namespace-quota-input"]'));
}
buttonSubmit() {
return new AsyncButtonPo(this.self().getId('form-save'));
}
tabContainerDefaultResourceLimit() {
return this.self().getId('btn-container-default-resource-limit');
}
@ -92,4 +82,28 @@ export default class ProjectNamespacePagePo extends PagePo {
bannerError(n: number) {
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 SecretsListPo from '@/cypress/e2e/po/lists/secrets-list.po';
import ProductNavPo from '@/cypress/e2e/po/side-bars/product-side-nav.po';
import BurgerMenuPo from '@/cypress/e2e/po/side-bars/burger-side-menu.po';
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) {
return `/c/${ clusterId }/explorer/secret`;
}
static goTo(clusterId: string): Cypress.Chainable<Cypress.AUTWindow> {
return super.goTo(SecretsPagePo.createPath(clusterId));
return super.goTo(SecretsListPagePo.createPath(clusterId));
}
constructor(clusterId: string) {
super(SecretsPagePo.createPath(clusterId));
super(SecretsListPagePo.createPath(clusterId));
}
secretsList(): SecretsListPo {
return new SecretsListPo('[data-testid="sortable-table-list-container"]');
static navTo(clusterId = 'local') {
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 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 { 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) {
return `/c/${ clusterId }/explorer/apps.daemonset`;
}
@ -19,29 +16,35 @@ export class WorkloadsDaemonsetsListPagePo extends PagePo {
constructor(clusterId = 'local') {
super(WorkloadsDaemonsetsListPagePo.createPath(clusterId));
}
}
masthead() {
return new ResourceListMastheadPo(this.self());
export class WorkLoadsDaemonsetsCreatePagePo extends BaseDetailPagePo {
static url: string;
private static createPath(clusterId: string, queryParams?: Record<string, string>) {
const urlStr = `/c/${ clusterId }/explorer/apps.daemonset/create`;
if (!queryParams) {
return urlStr;
}
const params = new URLSearchParams(queryParams);
return `${ urlStr }?${ params.toString() }`;
}
createDaemonset() {
return this.masthead().create();
static goTo(): Cypress.Chainable<Cypress.AUTWindow> {
return super.goTo(this.url);
}
goToeditItemWithName(name:string) {
const baseResourceList = new BaseResourceList(this.self());
constructor(clusterId = 'local', queryParams?: Record<string, string>) {
super(WorkLoadsDaemonsetsCreatePagePo.createPath(clusterId, queryParams));
return baseResourceList.actionMenu(name).getMenuItem('Edit Config').click();
}
listElementWithName(name:string) {
const baseResourceList = new BaseResourceList(this.self());
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;
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);
}
nameNsDescription() {
return new NameNsDescription(this.self());
}
containerImageInput(): LabeledInputPo {
return LabeledInputPo.byLabel(this.self(), 'Container Image');
}
@ -81,8 +80,4 @@ export class WorkLoadsDaemonsetsEditPagePo extends PagePo {
ScalingUpgradePolicyRadioBtn(): RadioGroupInputPo {
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 ContainerMountPathPo from '@/cypress/e2e/po/components/workloads/container-mount-paths.po';
import { WorkloadType } from '@shell/types/fleet';
import ProductNavPo from '@/cypress/e2e/po/side-bars/product-side-nav.po';
export class workloadDetailsPageBasePo extends PagePo {
static url: string;
@ -93,6 +94,12 @@ export class WorkloadsListPageBasePo extends PagePo {
super(WorkloadsListPageBasePo.createPath(clusterId, workloadType, queryParams));
}
static navTo() {
const sideNav = new ProductNavPo();
sideNav.navToSideMenuGroupByLabel('Workloads');
}
navigateToCreatePage() {
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 ChartRepositoriesCreateEditPo from '@/cypress/e2e/po/edit/chart-repositories.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 ResourceTablePo from '@/cypress/e2e/po/components/resource-table.po';
export default class ExtensionsPagePo extends PagePo {
static url = '/c/local/uiplugins'
@ -35,6 +36,10 @@ export default class ExtensionsPagePo extends PagePo {
return this.title().should('contain', 'Extensions');
}
catalogsList() {
return new ResourceTablePo('[data-testid="sortable-table-list-container"]');
}
loading() {
return this.self().get('.data-loading');
}
@ -55,7 +60,7 @@ export default class ExtensionsPagePo extends PagePo {
// we should be on the extensions page
this.waitForPage(null, 'available');
this.loading(MEDIUM_TIMEOUT_OPT).should('not.exist');
this.loading().should('not.exist');
// go to app repos
this.extensionMenuToggle();
@ -226,7 +231,7 @@ export default class ExtensionsPagePo extends PagePo {
}
extensionTabAllClick(): Cypress.Chainable {
return this.extensionTabs.clickNthTab(4);
return this.extensionTabs.clickTabWithName('all');
}
extensionTabBuiltinClick(): Cypress.Chainable {
@ -268,6 +273,10 @@ export default class ExtensionsPagePo extends PagePo {
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 ------------------
addReposModal() {
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();
}
// ------------------ Import Extension Catalog modal ------------------
importExtensionCatalogModal(): Cypress.Chainable {
return this.self().get('.plugin-install-dialog');
}
// ------------------ add a new repo (Extension Examples) ------------------
enterClusterRepoName(name: string) {
return new NameNsDescriptionPo(this.self()).name().set(name);

View File

@ -1,10 +1,9 @@
import PagePo from '@/cypress/e2e/po/pages/page.po';
import { SharedComponentsPo } from '@/cypress/e2e/po/components/shared-components/shared-components.po';
import { BaseListPagePo } from '@/cypress/e2e/po/pages/base/base-list-page.po';
import ResourceTablePo from '@/cypress/e2e/po/components/resource-table.po';
import BurgerMenuPo from '@/cypress/e2e/po/side-bars/burger-side-menu.po';
import { LONG_TIMEOUT_OPT } from '@/cypress/support/utils/timeouts';
export class FleetDashboardPagePo extends PagePo {
export class FleetDashboardListPagePo extends BaseListPagePo {
static url: string;
private static createPath(
@ -23,7 +22,7 @@ export class FleetDashboardPagePo extends PagePo {
}
static goTo(clusterId = 'local'): Cypress.Chainable<Cypress.AUTWindow> {
return super.goTo(FleetDashboardPagePo.createPath(clusterId));
return super.goTo(FleetDashboardListPagePo.createPath(clusterId));
}
static navTo() {
@ -33,11 +32,7 @@ export class FleetDashboardPagePo extends PagePo {
}
constructor(clusterId: string) {
super(FleetDashboardPagePo.createPath(clusterId));
}
sharedComponents() {
return new SharedComponentsPo(this.self());
super(FleetDashboardListPagePo.createPath(clusterId));
}
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 { SharedComponentsPo } from '@/cypress/e2e/po/components/shared-components/shared-components.po';
import { FleetDashboardPagePo } from '@/cypress/e2e/po/pages/fleet/fleet-dashboard.po';
import { FleetDashboardListPagePo } from '@/cypress/e2e/po/pages/fleet/fleet-dashboard.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`
constructor() {
@ -16,9 +16,9 @@ export class FleetBundlesListPagePo extends PagePo {
}
static navTo() {
const fleetDashboardPage = new FleetDashboardPagePo('_');
const fleetDashboardPage = new FleetDashboardListPagePo('_');
FleetDashboardPagePo.navTo();
FleetDashboardListPagePo.navTo();
fleetDashboardPage.waitForPage();
const sideNav = new ProductNavPo();
@ -26,12 +26,38 @@ export class FleetBundlesListPagePo extends PagePo {
sideNav.navToSideMenuGroupByLabel('Advanced');
sideNav.navToSideMenuEntryByLabel('Bundles');
}
}
sharedComponents() {
return new SharedComponentsPo(this.self());
export class FleetBundlesCreateEditPo extends BaseDetailPagePo {
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 {
return new FleetBundlesCreateEditPo(fleetWorkspace, id);
static goTo(path: string): Cypress.Chainable<Cypress.AUTWindow> {
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 { SharedComponentsPo } from '@/cypress/e2e/po/components/shared-components/shared-components.po';
import { FleetDashboardPagePo } from '@/cypress/e2e/po/pages/fleet/fleet-dashboard.po';
import { FleetDashboardListPagePo } from '@/cypress/e2e/po/pages/fleet/fleet-dashboard.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`
constructor() {
@ -16,9 +15,9 @@ export class FleetBundleNamespaceMappingListPagePo extends PagePo {
}
static navTo() {
const fleetDashboardPage = new FleetDashboardPagePo('_');
const fleetDashboardPage = new FleetDashboardListPagePo('_');
FleetDashboardPagePo.navTo();
FleetDashboardListPagePo.navTo();
fleetDashboardPage.waitForPage();
const sideNav = new ProductNavPo();
@ -26,12 +25,20 @@ export class FleetBundleNamespaceMappingListPagePo extends PagePo {
sideNav.navToSideMenuGroupByLabel('Advanced');
sideNav.navToSideMenuEntryByLabel('Bundle Namespace Mappings');
}
}
sharedComponents() {
return new SharedComponentsPo(this.self());
export class FleetBundleNsMappingCreateEditPo extends BaseDetailPagePo {
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 {
return new FleetBundleNsMappingCreateEditPo(fleetWorkspace, id);
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,11 +1,12 @@
import PagePo from '@/cypress/e2e/po/pages/page.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 { FleetDashboardListPagePo } from '@/cypress/e2e/po/pages/fleet/fleet-dashboard.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 { 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`
constructor() {
@ -17,9 +18,9 @@ export class FleetClusterListPagePo extends PagePo {
}
static navTo() {
const fleetDashboardPage = new FleetDashboardPagePo('_');
const fleetDashboardPage = new FleetDashboardListPagePo('_');
FleetDashboardPagePo.navTo();
FleetDashboardListPagePo.navTo();
fleetDashboardPage.waitForPage();
const sideNav = new ProductNavPo();
@ -27,10 +28,6 @@ export class FleetClusterListPagePo extends PagePo {
sideNav.navToSideMenuEntryByLabel('Clusters');
}
sharedComponents() {
return new SharedComponentsPo(this.self());
}
selectWorkspace(workspaceName = 'fleet-local') {
return this.header().selectWorkspace(workspaceName);
}
@ -43,3 +40,43 @@ export class FleetClusterListPagePo extends PagePo {
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 { SharedComponentsPo } from '@/cypress/e2e/po/components/shared-components/shared-components.po';
import { FleetDashboardPagePo } from '@/cypress/e2e/po/pages/fleet/fleet-dashboard.po';
import { FleetDashboardListPagePo } from '@/cypress/e2e/po/pages/fleet/fleet-dashboard.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) {
return `/c/${ clusterId }/fleet/fleet.cattle.io.clustergroup`;
}
@ -18,21 +19,51 @@ export class FleetClusterGroupsListPagePo extends PagePo {
}
static navTo() {
const fleetDashboardPage = new FleetDashboardPagePo('_');
const fleetDashboardPage = new FleetDashboardListPagePo('_');
FleetDashboardPagePo.navTo();
FleetDashboardListPagePo.navTo();
fleetDashboardPage.waitForPage();
const sideNav = new ProductNavPo();
sideNav.navToSideMenuEntryByLabel('Cluster Groups');
}
}
sharedComponents() {
return new SharedComponentsPo(this.self());
export class FleetClusterGroupsCreateEditPo extends BaseDetailPagePo {
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 {
return new FleetClusterGroupsCreateEditPo(this.clusterId, workspace, id);
static goTo(path: string): Cypress.Chainable<Cypress.AUTWindow> {
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 { SharedComponentsPo } from '@/cypress/e2e/po/components/shared-components/shared-components.po';
import { FleetDashboardPagePo } from '@/cypress/e2e/po/pages/fleet/fleet-dashboard.po';
import { FleetDashboardListPagePo } from '@/cypress/e2e/po/pages/fleet/fleet-dashboard.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`
constructor() {
@ -16,9 +15,9 @@ export class FleetClusterRegistrationTokenListPagePo extends PagePo {
}
static navTo() {
const fleetDashboardPage = new FleetDashboardPagePo('_');
const fleetDashboardPage = new FleetDashboardListPagePo('_');
FleetDashboardPagePo.navTo();
FleetDashboardListPagePo.navTo();
fleetDashboardPage.waitForPage();
const sideNav = new ProductNavPo();
@ -26,12 +25,20 @@ export class FleetClusterRegistrationTokenListPagePo extends PagePo {
sideNav.navToSideMenuGroupByLabel('Advanced');
sideNav.navToSideMenuEntryByLabel('Cluster Registration Tokens');
}
}
sharedComponents() {
return new SharedComponentsPo(this.self());
export class FleetTokensCreateEditPo extends BaseDetailPagePo {
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 {
return new FleetTokensCreateEditPo(fleetWorkspace, id);
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,10 +1,13 @@
import PagePo from '@/cypress/e2e/po/pages/page.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 { FleetDashboardListPagePo } from '@/cypress/e2e/po/pages/fleet/fleet-dashboard.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`
constructor() {
@ -16,9 +19,9 @@ export class FleetWorkspaceListPagePo extends PagePo {
}
static navTo() {
const fleetDashboardPage = new FleetDashboardPagePo('_');
const fleetDashboardPage = new FleetDashboardListPagePo('_');
FleetDashboardPagePo.navTo();
FleetDashboardListPagePo.navTo();
fleetDashboardPage.waitForPage();
const sideNav = new ProductNavPo();
@ -26,12 +29,54 @@ export class FleetWorkspaceListPagePo extends PagePo {
sideNav.navToSideMenuGroupByLabel('Advanced');
sideNav.navToSideMenuEntryByLabel('Workspaces');
}
}
sharedComponents() {
return new SharedComponentsPo(this.self());
export class FleetWorkspaceCreateEditPo extends BaseDetailPagePo {
private static createPath(fleetWorkspace?: string) {
const root = '/c/_/fleet/management.cattle.io.fleetworkspace';
return fleetWorkspace ? `${ root }/${ fleetWorkspace }` : `${ root }/create`;
}
createWorkspaceForm(fleetWorkspace?: string): FleetWorkspaceCreateEditPo {
return new FleetWorkspaceCreateEditPo(fleetWorkspace);
static goTo(path: string): Cypress.Chainable<Cypress.AUTWindow> {
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 { SharedComponentsPo } from '@/cypress/e2e/po/components/shared-components/shared-components.po';
import { FleetDashboardPagePo } from '@/cypress/e2e/po/pages/fleet/fleet-dashboard.po';
import { FleetDashboardListPagePo } from '@/cypress/e2e/po/pages/fleet/fleet-dashboard.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`
constructor() {
@ -15,19 +21,130 @@ export class FleetGitRepoListPagePo extends PagePo {
}
navTo() {
const fleetDashboardPage = new FleetDashboardPagePo('_');
const fleetDashboardPage = new FleetDashboardListPagePo('_');
FleetDashboardPagePo.navTo();
FleetDashboardListPagePo.navTo();
fleetDashboardPage.waitForPage();
const sideNav = new ProductNavPo();
sideNav.navToSideMenuEntryByLabel('Git Repos');
this.sharedComponents().list().checkVisible();
}
sharedComponents() {
return new SharedComponentsPo(this.self());
this.list().checkVisible();
}
}
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 { SharedComponentsPo } from '@/cypress/e2e/po/components/shared-components/shared-components.po';
import { FleetDashboardPagePo } from '@/cypress/e2e/po/pages/fleet/fleet-dashboard.po';
import { FleetDashboardListPagePo } from '@/cypress/e2e/po/pages/fleet/fleet-dashboard.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`
constructor() {
@ -16,9 +15,9 @@ export class FleetGitRepoRestrictionListPagePo extends PagePo {
}
static navTo() {
const fleetDashboardPage = new FleetDashboardPagePo('_');
const fleetDashboardPage = new FleetDashboardListPagePo('_');
FleetDashboardPagePo.navTo();
FleetDashboardListPagePo.navTo();
fleetDashboardPage.waitForPage();
const sideNav = new ProductNavPo();
@ -26,12 +25,20 @@ export class FleetGitRepoRestrictionListPagePo extends PagePo {
sideNav.navToSideMenuGroupByLabel('Advanced');
sideNav.navToSideMenuEntryByLabel('GitRepoRestrictions');
}
}
sharedComponents() {
return new SharedComponentsPo(this.self());
export class FleetRestrictionCreateEditPo extends BaseDetailPagePo {
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 {
return new FleetRestrictionCreateEditPo(fleetWorkspace, id);
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,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 CardPo from '@/cypress/e2e/po/components/card.po';
import LabeledSelectPo from '@/cypress/e2e/po/components/labeled-select.po';
export default class GenericPrompt extends ComponentPo {
card = new CardPo();
@ -12,11 +13,11 @@ export default class GenericPrompt extends ComponentPo {
return this.card.getBody();
}
cancel() {
return this.self().find('.btn role-secondary');
labeledSelect(selector = '.labeled-select'): LabeledSelectPo {
return new LabeledSelectPo(selector);
}
submit(text: string) {
clickActionButton(text: string) {
return this.card.getActionButton().contains(text).click();
}
}

View File

@ -24,7 +24,7 @@ export default class PromptRemove extends ComponentPo {
}
cancel() {
return this.self().get('.btn.role-secondary').click();
return this.self().get('.btn.role-secondary').contains('Cancel').click();
}
// 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 {
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() {
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 { HomeLinksPagePo } from '@/cypress/e2e/po/pages/global-settings/home-links.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('Login page', () => {
@ -78,11 +101,25 @@ describe('Shell a11y testing', { tags: ['@adminUser', '@accessibility'] }, () =>
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 createKeyPage = new CreateKeyPagePo();
it('Account', () => {
it('Account and API Keys Page', () => {
accountPage.goTo();
accountPage.waitForPage();
accountPage.title();
@ -91,7 +128,7 @@ describe('Shell a11y testing', { tags: ['@adminUser', '@accessibility'] }, () =>
cy.checkPageAccessibility();
});
it('Change password dialog', () => {
it('Change Password dialog', () => {
accountPage.changePassword();
accountPage.currentPassword().checkVisible();
cy.injectAxe();
@ -100,53 +137,380 @@ describe('Shell a11y testing', { tags: ['@adminUser', '@accessibility'] }, () =>
cy.checkElementAccessibility(el);
});
accountPage.cancel();
promptModal().clickActionButton('Cancel');
});
it('Create API key', () => {
it('API Key - Create', () => {
accountPage.create();
createKeyPage.waitForPage();
createKeyPage.mastheadTitle().then((el) => {
expect(el.trim()).to.include('API Key');
createKeyPage.mastheadTitle().then((title) => {
expect(title.replace(/\s+/g, ' ')).to.contain('API Key: Create');
});
cy.injectAxe();
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', () => {
const clusterDashboard = new ClusterDashboardPagePo('local');
describe('Explorer', () => {
describe('Cluster', () => {
const clusterDashboard = new ClusterDashboardPagePo('local');
it('Cluster dashboard page', () => {
ClusterDashboardPagePo.navTo();
clusterDashboard.waitForPage();
cy.injectAxe();
it('Cluster Dashboard page', () => {
clusterDashboard.goTo();
clusterDashboard.waitForPage();
cy.injectAxe();
cy.checkPageAccessibility();
});
it('Cluster appearance dialog', () => {
clusterDashboard.customizeAppearanceButton().click();
const customClusterCard = new CardPo();
customClusterCard.getTitle().contains('Cluster Appearance');
cy.injectAxe();
customClusterCard.self().then((el: any) => {
cy.checkElementAccessibility(el);
cy.checkPageAccessibility();
});
customClusterCard.getActionButton().contains('Cancel').click();
it('Cluster Appearance Modal', () => {
clusterDashboard.customizeAppearanceButton().click();
const customClusterCard = new CardPo();
customClusterCard.getTitle().contains('Cluster Appearance');
cy.injectAxe();
customClusterCard.self().then((el: any) => {
cy.checkElementAccessibility(el);
});
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', () => {
it('Clusters - Create page', () => {
const createClusterPage = new ClusterManagerCreatePagePo();
const loadingPo = new LoadingPo('.loading-indicator');
const createClusterPage = new ClusterManagerCreatePagePo();
const loadingPo = new LoadingPo('.loading-indicator');
it('Clusters - Create page', () => {
createClusterPage.goTo();
createClusterPage.waitForPage();
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', () => {
const podSecurityAdmissionsPage = new PodSecurityAdmissionsPagePo();
@ -201,133 +632,230 @@ describe('Shell a11y testing', { tags: ['@adminUser', '@accessibility'] }, () =>
});
});
it('Deployments page', () => {
const deploymentsListPage = new WorkloadsDeploymentsListPagePo();
describe('Users', () => {
const usersPo = new UsersPo('_');
deploymentsListPage.goTo();
deploymentsListPage.waitForPage();
deploymentsListPage.sortableTable().checkLoadingIndicatorNotVisible();
// expand the health scale up/down control
deploymentsListPage.sortableTable().getTableCell(1, 10).click();
cy.injectAxe();
it('Users page', () => {
cy.intercept('GET', `${ USERS_BASE_URL }?exclude=metadata.managedFields`).as('getUsers');
cy.checkPageAccessibility();
usersPo.goTo();
usersPo.waitForPage();
usersPo.list().masthead().title().should('contain', 'Users');
cy.wait('@getUsers');
usersPo.list().resourceTable().sortableTable().checkLoadingIndicatorNotVisible();
usersPo.list().refreshGroupMembership().checkVisible();
cy.injectAxe();
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();
});
});
it('Charts page', () => {
const chartsPage = new ChartsPage();
describe('Charts', () => {
it('Charts page', () => {
const chartsPage = new ChartsPage();
ChartsPage.navTo();
chartsPage.waitForPage();
chartsPage.chartsCarouselSlides().should('be.visible');
cy.injectAxe();
ChartsPage.navTo();
chartsPage.waitForPage();
chartsPage.chartsCarouselSlides().should('be.visible');
cy.injectAxe();
cy.checkPageAccessibility();
cy.checkPageAccessibility();
});
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();
});
});
it('Extensions page', () => {
describe('Extensions', () => {
const extensionsPo = new ExtensionsPagePo();
// Set the preference
cy.setUserPreference({ 'plugin-developer': true });
it('Extensions page', () => {
// Set the preference
cy.setUserPreference({ 'plugin-developer': true });
extensionsPo.goTo();
extensionsPo.waitForPage(null, 'available');
extensionsPo.loading().should('not.exist');
extensionsPo.extensionTabBuiltin().checkExists();
extensionsPo.extensionTabBuiltinClick();
extensionsPo.waitForPage(null, 'builtin');
extensionsPo.extensionCard('aks').should('be.visible');
cy.injectAxe();
extensionsPo.goTo();
extensionsPo.waitForPage(null, 'available');
extensionsPo.loading().should('not.exist');
extensionsPo.extensionTabAllClick();
extensionsPo.waitForPage(null, 'all');
extensionsPo.extensionCard('aks').should('be.visible');
cy.injectAxe();
cy.checkPageAccessibility();
});
it('Global Settings page', () => {
const settingsPage = new SettingsPagePo('local');
SettingsPagePo.navTo();
settingsPage.waitForPage();
cy.injectAxe();
cy.checkPageAccessibility();
// expand menu
settingsPage.actionButtonByLabel('engine-install-url').click();
settingsPage.editSettingsButton().should('be.visible');
cy.injectAxe();
settingsPage.editSettingsButton().then((el) => {
cy.checkElementAccessibility(el);
});
});
it('Home Links page', () => {
const homeLinksPage = new HomeLinksPagePo();
HomeLinksPagePo.navTo();
homeLinksPage.addLinkButton().click();
homeLinksPage.displayTextInput().checkVisible();
homeLinksPage.urlInput().checkVisible();
cy.injectAxe();
cy.checkPageAccessibility();
});
});
describe('Menus', { testIsolation: 'off' }, () => {
const homePage = new HomePagePo();
const burgerMenu = new BurgerMenuPo();
const userMenu = new UserMenuPo();
before(() => {
cy.login();
});
it('User Menu', () => {
HomePagePo.navTo();
homePage.waitForPage();
userMenu.ensureOpen();
cy.injectAxe();
userMenu.userMenuContainer().then((el: any) => {
cy.checkElementAccessibility(el);
});
});
it('Burger Menu', () => {
HomePagePo.navTo();
homePage.waitForPage();
burgerMenu.checkVisible();
BurgerMenuPo.toggle();
cy.injectAxe();
burgerMenu.self().then((el: any) => {
cy.checkElementAccessibility(el);
cy.checkPageAccessibility();
});
burgerMenu.brandLogoImage().then((el: any) => {
cy.checkElementAccessibility(el);
});
});
it('Add Rancher Repositories Modal', () => {
extensionsPo.extensionMenuToggle();
extensionsPo.addRepositoriesClick();
dialogModal().checkVisible();
it('Product Side navigation', () => {
const clusterDashboard = new ClusterDashboardPagePo('local');
cy.injectAxe();
clusterDashboard.goTo();
clusterDashboard.waitForPage();
cy.injectAxe();
const sideNav = new ProductNavPo();
const sideNavOptions = ['Cluster', 'Workloads', 'Apps', 'Service Discovery', 'Storage', 'Policy', 'More Resources'];
// expand each side nav option and check accessibility
sideNavOptions.forEach((option) => {
sideNav.navToSideMenuGroupByLabel(option);
sideNav.self().then((el: any) => {
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');
SettingsPagePo.navTo();
settingsPage.waitForPage();
cy.injectAxe();
cy.checkPageAccessibility();
// expand menu
settingsPage.actionButtonByLabel('engine-install-url').click();
settingsPage.editSettingsButton().should('be.visible');
cy.injectAxe();
settingsPage.editSettingsButton().then((el) => {
cy.checkElementAccessibility(el);
});
});
it('Home Links page', () => {
const homeLinksPage = new HomeLinksPagePo();
HomeLinksPagePo.navTo();
homeLinksPage.addLinkButton().click();
homeLinksPage.displayTextInput().checkVisible();
homeLinksPage.urlInput().checkVisible();
cy.injectAxe();
cy.checkPageAccessibility();
});
it('Branding page', () => {
const brandingPage = new BrandingPagePo();
BrandingPagePo.navTo();
brandingPage.privateLabel().checkVisible();
cy.injectAxe();
cy.checkPageAccessibility();
});
it('Banners page', () => {
const bannersPage = new BannersPagePo();
BannersPagePo.navTo();
bannersPage.headerBannerCheckbox().checkVisible();
cy.injectAxe();
cy.checkPageAccessibility();
});
});
describe('Menus', () => {
const burgerMenu = new BurgerMenuPo();
it('User Menu', () => {
const userMenu = new UserMenuPo();
userMenu.ensureOpen();
cy.injectAxe();
userMenu.userMenuContainer().then((el: any) => {
cy.checkElementAccessibility(el);
});
});
it('Burger Menu', () => {
// HomePagePo.navTo();
// homePage.waitForPage();
burgerMenu.checkVisible();
BurgerMenuPo.toggle();
cy.injectAxe();
burgerMenu.self().then((el: any) => {
cy.checkElementAccessibility(el);
});
burgerMenu.brandLogoImage().then((el: any) => {
cy.checkElementAccessibility(el);
});
});
it('Product Side navigation', () => {
const clusterDashboard = new ClusterDashboardPagePo('local');
clusterDashboard.goTo();
clusterDashboard.waitForPage();
cy.injectAxe();
const sideNav = new ProductNavPo();
const sideNavOptions = ['Cluster', 'Workloads', 'Apps', 'Service Discovery', 'Storage', 'Policy', 'More Resources'];
// expand each side nav option and check accessibility
sideNavOptions.forEach((option) => {
sideNav.navToSideMenuGroupByLabel(option);
sideNav.self().then((el: any) => {
cy.checkElementAccessibility(el);
});
});
});
});
});

View File

@ -7,7 +7,7 @@ import { LoggingClusterflowEditPagePo, LoggingClusterflowListPagePo } from '@/cy
import Kubectl from '@/cypress/e2e/po/components/kubectl.po';
import ClusterToolsPagePo from '@/cypress/e2e/po/pages/explorer/cluster-tools.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 { 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');
const clusterTools = new ClusterToolsPagePo('local');
const installedAppsPage = new ChartInstalledAppsPagePo('local', 'apps');
const installedAppsPage = new ChartInstalledAppsListPagePo('local', 'apps');
installedAppsPage.goTo();
installedAppsPage.waitForPage();
installedAppsPage.sharedComponents(MEDIUM_TIMEOUT_OPT).resourceTable().sortableTable().checkLoadingIndicatorNotVisible();
installedAppsPage.sharedComponents().resourceTable().sortableTable().noRowsShouldNotExist();
installedAppsPage.sharedComponents().resourceTableDetails(chartApp, 1).should('exist');
installedAppsPage.sharedComponents().resourceTableDetails(chartCrd, 1).should('exist');
cy.wait('@getCharts', MEDIUM_TIMEOUT_OPT).its('response.statusCode').should('eq', 200);
installedAppsPage.appsList().sortableTable().checkLoadingIndicatorNotVisible();
installedAppsPage.appsList().sortableTable().noRowsShouldNotExist();
installedAppsPage.appsList().resourceTableDetails(chartApp, 1).should('exist');
installedAppsPage.appsList().resourceTableDetails(chartCrd, 1).should('exist');
clusterTools.goTo();
clusterTools.waitForPage();
@ -110,13 +111,13 @@ describe('Logging Chart', { testIsolation: 'off', tags: ['@charts', '@adminUser'
installedAppsPage.goTo();
installedAppsPage.waitForPage();
installedAppsPage.sharedComponents(MEDIUM_TIMEOUT_OPT).resourceTable().sortableTable().checkLoadingIndicatorNotVisible();
installedAppsPage.sharedComponents().resourceTable().sortableTable().noRowsShouldNotExist();
installedAppsPage.sharedComponents().resourceTable().sortableTable().rowNames('.col-link-detail', MEDIUM_TIMEOUT_OPT)
cy.wait('@getCharts', MEDIUM_TIMEOUT_OPT).its('response.statusCode').should('eq', 200);
installedAppsPage.appsList().sortableTable().checkLoadingIndicatorNotVisible();
installedAppsPage.appsList().sortableTable().noRowsShouldNotExist();
installedAppsPage.appsList().sortableTable().rowNames('.col-link-detail', MEDIUM_TIMEOUT_OPT)
.should('not.contain', chartApp);
// 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', () => {

View File

@ -1,6 +1,6 @@
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';
const certName = 'expired';
@ -102,7 +102,7 @@ describe('Certificates', { testIsolation: 'off', tags: ['@explorer', '@adminUser
clusterDashboard.fullSecretsList().scrollIntoView();
clusterDashboard.fullSecretsList().click();
const secrets = new SecretsPagePo('local');
const secrets = new SecretsListPagePo('local');
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 { WorkloadsDeploymentsListPagePo } from '@/cypress/e2e/po/pages/explorer/workloads/workloads-deployments.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 { 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().closeTerminal();
header.kubectlShell().checkNotVisible();
});
it('can download kubeconfig from header', () => {
@ -245,15 +244,16 @@ describe('Cluster Dashboard', { testIsolation: 'off', tags: ['@explorer', '@admi
clusterDashboard.waitForPage(undefined, 'cluster-events');
// Check events
clusterDashboard.eventsList().resourceTable().sortableTable().rowElements()
clusterDashboard.eventsList().sortableTable().rowElements()
.should('have.length.gte', 2);
clusterDashboard.fullEventsLink().click();
const events = new EventsPagePo('local');
const events = new EventsPageListPo('local');
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'] }, () => {
@ -263,7 +263,7 @@ describe('Cluster Dashboard', { testIsolation: 'off', tags: ['@explorer', '@admi
cy.wait('@eventsNoData');
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'];
@ -272,10 +272,10 @@ describe('Cluster Dashboard', { testIsolation: 'off', tags: ['@explorer', '@admi
expectedHeaders = ['Reason', 'Object', 'Message', 'Name', 'First Seen', 'Last Seen', 'Count'];
}
clusterDashboard.eventsList().resourceTable().sortableTable().tableHeaderRow()
clusterDashboard.eventsList().sortableTable().tableHeaderRow()
.self()
.scrollIntoView();
clusterDashboard.eventsList().resourceTable().sortableTable().tableHeaderRow()
clusterDashboard.eventsList().sortableTable().tableHeaderRow()
.within('.table-header-container .content')
.each((el, i) => {
expect(el.text().trim()).to.eq(expectedHeaders[i]);
@ -283,16 +283,16 @@ describe('Cluster Dashboard', { testIsolation: 'off', tags: ['@explorer', '@admi
clusterDashboard.fullEventsLink().click();
cy.wait('@eventsNoData');
const events = new EventsPagePo('local');
const events = new EventsPageListPo('local');
events.waitForPage();
events.eventslist().resourceTable().sortableTable().checkRowCount(true, 1);
events.list().resourceTable().sortableTable().checkRowCount(true, 1);
const expectedFullHeaders = ['State', 'Last Seen', 'Type', 'Reason', 'Object',
'Subobject', 'Source', 'Message', 'First Seen', 'Count', 'Name', 'Namespace'];
events.eventslist().resourceTable().sortableTable().tableHeaderRow()
events.list().resourceTable().sortableTable().tableHeaderRow()
.within('.table-header-container .content')
.each((el, 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 { 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 LoadingPo from '@/cypress/e2e/po/components/loading.po';
import SortableTablePo from '@/cypress/e2e/po/components/sortable-table.po';
const cluster = 'local';
const clusterDashboard = new ClusterDashboardPagePo(cluster);
const events = new EventsPagePo(cluster);
const events = new EventsPageListPo(cluster);
const pageSize = 10;
// Should be enough to create at least 3 pages of events
const podCount = 15;
@ -87,7 +87,7 @@ describe('Events', { testIsolation: 'off', tags: ['@explorer', '@adminUser'] },
ClusterDashboardPagePo.goToAndConfirmNsValues(cluster, { all: { is: true } });
clusterDashboard.waitForPage(undefined, 'cluster-events');
EventsPagePo.navTo();
EventsPageListPo.navTo();
events.waitForPage();
let vaiCacheEnabled = false;
@ -110,150 +110,215 @@ describe('Events', { testIsolation: 'off', tags: ['@explorer', '@adminUser'] },
expect(initialCount).to.be.greaterThan(3 * pageSize);
// pagination is visible
events.sortableTable().pagination().checkVisible();
events.list().resourceTable().sortableTable().pagination()
.checkVisible();
const loadingPo = new LoadingPo('.title .resource-loading-indicator');
loadingPo.checkNotExists();
// basic checks on navigation buttons
events.sortableTable().pagination().beginningButton().isDisabled();
events.sortableTable().pagination().leftButton().isDisabled();
events.sortableTable().pagination().rightButton().isEnabled();
events.sortableTable().pagination().endButton().isEnabled();
events.list().resourceTable().sortableTable().pagination()
.beginningButton()
.isDisabled();
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
events.sortableTable().pagination().self().scrollIntoView();
events.sortableTable().pagination().paginationText().then((el) => {
expect(el.trim()).to.eq(`1 - ${ pageSize } of ${ initialCount } Events`);
});
events.list().resourceTable().sortableTable().pagination()
.self()
.scrollIntoView();
events.list().resourceTable().sortableTable().pagination()
.paginationText()
.then((el) => {
expect(el.trim()).to.eq(`1 - ${ pageSize } of ${ initialCount } Events`);
});
// navigate to next page - right button
countHelper.setupCount(vaiCacheEnabled, initialCount);
events.sortableTable().pagination().rightButton().click();
events.list().resourceTable().sortableTable().pagination()
.rightButton()
.click();
countHelper.handleCount(vaiCacheEnabled);
// check text and buttons after navigation
events.sortableTable().pagination().self().scrollIntoView();
events.list().resourceTable().sortableTable().pagination()
.self()
.scrollIntoView();
countHelper.getCount().then((count) => {
return events.sortableTable().pagination().paginationText().then((el) => {
expect(el.trim()).to.eq(`${ pageSize + 1 } - ${ 2 * pageSize } of ${ count } Events`);
});
return events.list().resourceTable().sortableTable().pagination()
.paginationText()
.then((el) => {
expect(el.trim()).to.eq(`${ pageSize + 1 } - ${ 2 * pageSize } of ${ count } Events`);
});
});
events.sortableTable().pagination().beginningButton().isEnabled();
events.sortableTable().pagination().leftButton().isEnabled();
events.list().resourceTable().sortableTable().pagination()
.beginningButton()
.isEnabled();
events.list().resourceTable().sortableTable().pagination()
.leftButton()
.isEnabled();
// navigate to first page - left button
countHelper.setupCount(vaiCacheEnabled, initialCount);
events.sortableTable().pagination().leftButton().click();
events.list().resourceTable().sortableTable().pagination()
.leftButton()
.click();
countHelper.handleCount(vaiCacheEnabled);
// check text and buttons after navigation
events.sortableTable().pagination().self().scrollIntoView();
events.list().resourceTable().sortableTable().pagination()
.self()
.scrollIntoView();
countHelper.getCount().then((count) => {
return events.sortableTable().pagination().paginationText().then((el) => {
expect(el.trim()).to.eq(`1 - ${ pageSize } of ${ count } Events`);
});
return events.list().resourceTable().sortableTable().pagination()
.paginationText()
.then((el) => {
expect(el.trim()).to.eq(`1 - ${ pageSize } of ${ count } Events`);
});
});
events.sortableTable().pagination().beginningButton().isDisabled();
events.sortableTable().pagination().leftButton().isDisabled();
events.list().resourceTable().sortableTable().pagination()
.beginningButton()
.isDisabled();
events.list().resourceTable().sortableTable().pagination()
.leftButton()
.isDisabled();
// navigate to last page - end button
countHelper.setupCount(vaiCacheEnabled, initialCount);
events.sortableTable().pagination().endButton().scrollIntoView()
events.list().resourceTable().sortableTable().pagination()
.endButton()
.scrollIntoView()
.click();
countHelper.handleCount(vaiCacheEnabled);
// check text after navigation
events.sortableTable().pagination().self().scrollIntoView();
events.list().resourceTable().sortableTable().pagination()
.self()
.scrollIntoView();
countHelper.getCount().then((count) => {
return events.sortableTable().pagination().paginationText().then((el) => {
let pages = Math.floor(count / pageSize);
return events.list().resourceTable().sortableTable().pagination()
.paginationText()
.then((el) => {
let pages = Math.floor(count / pageSize);
if (count % pageSize === 0) {
pages--;
}
const from = (pages * pageSize) + 1;
const to = count;
if (count % pageSize === 0) {
pages--;
}
const from = (pages * pageSize) + 1;
const to = count;
expect(el.trim()).to.eq(`${ from } - ${ to } of ${ to } Events`);
});
expect(el.trim()).to.eq(`${ from } - ${ to } of ${ to } Events`);
});
});
// navigate to first page - beginning button
countHelper.setupCount(vaiCacheEnabled, initialCount);
events.sortableTable().pagination().beginningButton().click();
events.list().resourceTable().sortableTable().pagination()
.beginningButton()
.click();
countHelper.handleCount(vaiCacheEnabled);
// check text and buttons after navigation
events.sortableTable().pagination().self().scrollIntoView();
events.list().resourceTable().sortableTable().pagination()
.self()
.scrollIntoView();
countHelper.getCount().then((count) => {
events.sortableTable().pagination().paginationText().then((el) => {
expect(el.trim()).to.eq(`1 - ${ pageSize } of ${ count } Events`);
});
events.list().resourceTable().sortableTable().pagination()
.paginationText()
.then((el) => {
expect(el.trim()).to.eq(`1 - ${ pageSize } of ${ count } Events`);
});
});
events.sortableTable().pagination().beginningButton().isDisabled();
events.sortableTable().pagination().leftButton().isDisabled();
events.list().resourceTable().sortableTable().pagination()
.beginningButton()
.isDisabled();
events.list().resourceTable().sortableTable().pagination()
.leftButton()
.isDisabled();
});
});
it('filter events', () => {
ClusterDashboardPagePo.navTo();
clusterDashboard.waitForPage(undefined, 'cluster-events');
EventsPagePo.navTo();
EventsPageListPo.navTo();
events.waitForPage();
events.sortableTable().checkVisible();
events.sortableTable().checkLoadingIndicatorNotVisible();
events.sortableTable().checkRowCount(false, pageSize);
events.list().resourceTable().sortableTable().checkVisible();
events.list().resourceTable().sortableTable().checkLoadingIndicatorNotVisible();
events.list().resourceTable().sortableTable().checkRowCount(false, pageSize);
// filter by namespace
events.sortableTable().filter(nsName2);
events.list().resourceTable().sortableTable().filter(nsName2);
events.waitForPage(`q=${ nsName2 }`);
events.eventslist().resourceTable().sortableTable().rowElementWithPartialName(uniquePod)
events.list().resourceTable().sortableTable().rowElementWithPartialName(uniquePod)
.should('have.length.lte', 5);
events.sortableTable().rowElementWithPartialName(uniquePod).should('be.visible');
events.list().resourceTable().sortableTable().rowElementWithPartialName(uniquePod)
.should('be.visible');
// filter by name
events.sortableTable().filter(uniquePod);
events.list().resourceTable().sortableTable().filter(uniquePod);
events.waitForPage(`q=${ uniquePod }`);
events.eventslist().resourceTable().sortableTable().rowElementWithPartialName(uniquePod)
events.list().resourceTable().sortableTable().rowElementWithPartialName(uniquePod)
.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', () => {
EventsPagePo.navTo();
EventsPageListPo.navTo();
events.waitForPage();
// 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
events.sortableTable().sort(11).click();
events.sortableTable().tableHeaderRow().checkSortOrder(11, 'down');
events.list().resourceTable().sortableTable().sort(11)
.click();
events.list().resourceTable().sortableTable().tableHeaderRow()
.checkSortOrder(11, 'down');
// event name should be visible on first page (sorted in ASC order)
events.sortableTable().tableHeaderRow().self().scrollIntoView();
events.sortableTable().rowElementWithPartialName(uniquePod).scrollIntoView().should('be.visible');
events.list().resourceTable().sortableTable().tableHeaderRow()
.self()
.scrollIntoView();
events.list().resourceTable().sortableTable().rowElementWithPartialName(uniquePod)
.scrollIntoView()
.should('be.visible');
// sort by name in DESC order
events.sortableTable().sort(11).click();
events.sortableTable().tableHeaderRow().checkSortOrder(11, 'up');
events.list().resourceTable().sortableTable().sort(11)
.click();
events.list().resourceTable().sortableTable().tableHeaderRow()
.checkSortOrder(11, 'up');
// 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
events.sortableTable().pagination().endButton().scrollIntoView()
events.list().resourceTable().sortableTable().pagination()
.endButton()
.scrollIntoView()
.click();
// event name should be visible on last page (sorted in DESC order)
events.sortableTable().rowElementWithPartialName(uniquePod).scrollIntoView().should('be.visible');
events.list().resourceTable().sortableTable().rowElementWithPartialName(uniquePod)
.scrollIntoView()
.should('be.visible');
});
it('pagination is hidden', () => {
@ -263,10 +328,11 @@ describe('Events', { testIsolation: 'off', tags: ['@explorer', '@adminUser'] },
events.waitForPage();
cy.wait('@eventsDataSmall');
events.sortableTable().checkVisible();
events.sortableTable().checkLoadingIndicatorNotVisible();
events.sortableTable().checkRowCount(false, 3);
events.sortableTable().pagination().checkNotExists();
events.list().resourceTable().sortableTable().checkVisible();
events.list().resourceTable().sortableTable().checkLoadingIndicatorNotVisible();
events.list().resourceTable().sortableTable().checkRowCount(false, 3);
events.list().resourceTable().sortableTable().pagination()
.checkNotExists();
});
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';
describe('Projects/Namespaces', { tags: ['@explorer2', '@adminUser'] }, () => {
const projectsNamespacesPage = new ProjectsNamespacesPagePo('local');
const projectsNamespacesPage = new ProjectsNamespacesListPagePo();
const createProjectPage = new ProjectCreateEditPagePo();
const createNamespacePage = new NamespaceCreateEditPagePo();
beforeEach(() => {
cy.login();
@ -11,13 +13,18 @@ describe('Projects/Namespaces', { tags: ['@explorer2', '@adminUser'] }, () => {
});
it('flat list view should have create Namespace button', () => {
projectsNamespacesPage.flatListClick();
projectsNamespacesPage.createProjectNamespaceButton().should('exist');
projectsNamespacesPage.list().resourceTable().sortableTable().groupByButtons(0)
.click();
projectsNamespacesPage.createNamespaceButton().should('exist');
projectsNamespacesPage.baseResourceList().masthead().actions().contains('Create Project')
.should('exist');
});
it('create namespace screen should have a projects dropdown', () => {
projectsNamespacesPage.createProjectNamespaceClick();
projectsNamespacesPage.nsProject().checkExists();
projectsNamespacesPage.createNamespaceButton().click();
createNamespacePage.resourceDetail().createEditView().nameNsDescription()
.project()
.checkExists();
});
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
spoofThirdPartyPrincipal();
projectsNamespacesPage.createProjectButtonClick();
projectsNamespacesPage.name().set(projectName);
projectsNamespacesPage.buttonSubmit().click();
projectsNamespacesPage.baseResourceList().masthead().create();
createProjectPage.resourceDetail().createEditView().nameNsDescription()
.name()
.set(projectName);
createProjectPage.resourceDetail().createEditView()
.create()
.click();
cy.wait('@createProjectRequest').then(({ request }) => {
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', () => {
cy.get('@projectName').then((projectName) => {
projectsNamespacesPage.createProjectButtonClick();
projectsNamespacesPage.name().set(projectName);
projectsNamespacesPage.buttonSubmit().click();
projectsNamespacesPage.baseResourceList().masthead().create();
createProjectPage.resourceDetail().createEditView().nameNsDescription()
.name()
.set(projectName);
createProjectPage.resourceDetail().createEditView()
.create();
cy.wait('@createProjectRequest').then(({ request, response }) => {
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(() => {
cy.get('@projectName').then((projectName) => {
cy.get<string>('@projectName').then((projectName) => {
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
it('Create button becomes available if the name is filled in', () => {
projectsNamespacesPage.createProjectButtonClick();
projectsNamespacesPage.buttonSubmit().expectToBeDisabled();
projectsNamespacesPage.name().set('test-1234');
projectsNamespacesPage.buttonSubmit().expectToBeEnabled();
projectsNamespacesPage.baseResourceList().masthead().create();
createProjectPage.resourceDetail().createEditView()
.createButton()
.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', () => {
projectsNamespacesPage.createProjectButtonClick();
projectsNamespacesPage.baseResourceList().masthead().create();
projectsNamespacesPage.name().set('test-1234');
projectsNamespacesPage.tabResourceQuotas().click();
projectsNamespacesPage.btnAddResource().click();
projectsNamespacesPage.inputProjectLimit().set('50');
projectsNamespacesPage.buttonSubmit().click();
createProjectPage.resourceDetail().createEditView().nameNsDescription()
.name()
.set('test-1234');
createProjectPage.tabResourceQuotas().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');
projectsNamespacesPage.bannerError(0).should('have.length', 1);
createProjectPage.bannerError(0).should('be.visible').contains('does not have all fields defined on a resourceQuota');
createProjectPage.bannerError(0).should('have.length', 1);
});
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');
projectsNamespacesPage.tabResourceQuotas().click();
projectsNamespacesPage.btnAddResource().click();
projectsNamespacesPage.inputProjectLimit().set('50');
projectsNamespacesPage.buttonSubmit().click();
createProjectPage.resourceDetail().createEditView().nameNsDescription()
.name()
.set('test-1234');
createProjectPage.tabResourceQuotas().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');
projectsNamespacesPage.bannerError(0).should('have.length', 1);
createProjectPage.bannerError(0).should('be.visible').contains('does not have all fields defined on a resourceQuota');
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');
projectsNamespacesPage.bannerError(0).should('have.length', 1);
projectsNamespacesPage.bannerError(1).should('have.length', 0);
createProjectPage.bannerError(0).should('be.visible').contains('does not have all fields defined on a resourceQuota');
createProjectPage.bannerError(0).should('have.length', 1);
createProjectPage.bannerError(1).should('have.length', 0);
});
// https://github.com/rancher/dashboard/issues/11881
// it.skip('displays the most recent error after resolving a single error in a form with multiple errors', () => {
// projectsNamespacesPage.createProjectButtonClick();
// testing https://github.com/rancher/dashboard/issues/11881
it('displays the most recent error after resolving a single error in a form with multiple errors', () => {
projectsNamespacesPage.baseResourceList().masthead().create();
// // Create the first error
// projectsNamespacesPage.name().set('test-1234');
// projectsNamespacesPage.tabResourceQuotas().click();
// projectsNamespacesPage.btnAddResource().click();
// projectsNamespacesPage.inputProjectLimit().set('50');
// projectsNamespacesPage.buttonSubmit().click();
// Create the first error
createProjectPage.resourceDetail().createEditView().nameNsDescription()
.name()
.set('test-1234');
createProjectPage.tabResourceQuotas().click();
createProjectPage.btnAddResource().click();
createProjectPage.inputProjectLimit().set('50');
createProjectPage.resourceDetail().createEditView()
.create();
// // Create a second error
// projectsNamespacesPage.tabContainerDefaultResourceLimit().click();
// projectsNamespacesPage.inputCpuReservation().set('1000');
// projectsNamespacesPage.inputMemoryReservation().set('128');
// projectsNamespacesPage.inputCpuLimit().set('200');
// projectsNamespacesPage.inputMemoryLimit().set('64');
// projectsNamespacesPage.buttonSubmit().click();
// Create a second error
createProjectPage.tabContainerDefaultResourceLimit().click();
createProjectPage.inputCpuReservation().set('1000');
createProjectPage.inputMemoryReservation().set('128');
createProjectPage.inputCpuLimit().set('200');
createProjectPage.inputMemoryLimit().set('64');
createProjectPage.resourceDetail().createEditView()
.create();
// // Assert that there is only a single error message
// projectsNamespacesPage.bannerError(0).should('be.visible').contains('does not have all fields defined on a resourceQuota');
// projectsNamespacesPage.bannerError(0).should('have.length', 1);
// projectsNamespacesPage.bannerError(1).should('have.length', 0);
// Assert that there is only a single error message
createProjectPage.bannerError(0).should('be.visible').contains('does not have all fields defined on a resourceQuota');
createProjectPage.bannerError(0).should('have.length', 1);
createProjectPage.bannerError(1).should('have.length', 0);
// // resolve the first error
// projectsNamespacesPage.tabResourceQuotas().click();
// projectsNamespacesPage.inputNamespaceDefaultLimit().set('50');
// projectsNamespacesPage.buttonSubmit().click();
// resolve the first error
createProjectPage.tabResourceQuotas().click();
createProjectPage.inputNamespaceDefaultLimit().set('50');
createProjectPage.resourceDetail().createEditView()
.create();
// // Click on Create again and assert that there is only a single error
// projectsNamespacesPage.bannerError(0).should('be.visible').contains('admission webhook "rancher.cattle.io.projects.management.cattle.io" denied the request');
// projectsNamespacesPage.bannerError(0).should('have.length', 1);
// projectsNamespacesPage.bannerError(1).should('have.length', 0);
// });
// Click on Create again and assert that there is only a single error
createProjectPage.bannerError(0).should('be.visible').contains('admission webhook "rancher.cattle.io.projects.management.cattle.io" denied the request');
createProjectPage.bannerError(0).should('have.length', 1);
createProjectPage.bannerError(1).should('have.length', 0);
});
});
});

View File

@ -24,26 +24,35 @@ describe('Cluster Explorer', { tags: ['@explorer2', '@adminUser'] }, () => {
workloadsDaemonsetsListPage.goTo();
workloadsDaemonsetsListPage.waitForPage();
workloadsDaemonsetsListPage.createDaemonset();
workloadsDaemonsetsListPage.baseResourceList().masthead().create();
// create a new daemonset
const workloadsDaemonsetsEditPage = new WorkLoadsDaemonsetsEditPagePo('local');
workloadsDaemonsetsEditPage.nameNsDescription().name().set(daemonsetName);
workloadsDaemonsetsEditPage.resourceDetail().createEditView().nameNsDescription()
.name()
.set(daemonsetName);
workloadsDaemonsetsEditPage.containerImageInput().set('nginx');
workloadsDaemonsetsEditPage.saveCreateForm().click();
workloadsDaemonsetsEditPage.resourceDetail().cruResource().saveOrCreate()
.click();
workloadsDaemonsetsListPage.waitForPage();
workloadsDaemonsetsListPage.listElementWithName(daemonsetName).should('be.visible');
workloadsDaemonsetsListPage.goToeditItemWithName(daemonsetName);
workloadsDaemonsetsListPage.list().resourceTable().sortableTable()
.rowElementWithName(daemonsetName)
.should('be.visible');
workloadsDaemonsetsListPage.list().actionMenu(daemonsetName).getMenuItem('Edit Config')
.click();
// edit daemonset
workloadsDaemonsetsEditPage.clickTab('#DaemonSet');
workloadsDaemonsetsEditPage.clickTab('#upgrading');
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) => {
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 * as path from 'path';
import * as jsyaml from 'js-yaml';
@ -12,7 +12,7 @@ const mappingsNameList = [];
const downloadsFolder = Cypress.config('downloadsFolder');
describe('Bundle Namespace Mappings', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] }, () => {
const fleetBundleNsMappingsPage = new FleetBundleNamespaceMappingListPagePo();
const fleetBundleNsMappingsListPage = new FleetBundleNamespaceMappingListPagePo();
const headerPo = new HeaderPo();
describe('CRUD', { tags: ['@fleet', '@adminUser'] }, () => {
@ -24,19 +24,21 @@ describe('Bundle Namespace Mappings', { testIsolation: 'off', tags: ['@fleet', '
});
it('can create a bundle namespace mapping', () => {
const fleetBundleNsMappingCreateEditPage = new FleetBundleNsMappingCreateEditPo();
cy.intercept('POST', '/v1/fleet.cattle.io.bundlenamespacemappings').as('createMapping');
fleetBundleNsMappingsPage.goTo();
fleetBundleNsMappingsPage.waitForPage();
fleetBundleNsMappingsPage.sharedComponents().baseResourceList().masthead().title()
fleetBundleNsMappingsListPage.goTo();
fleetBundleNsMappingsListPage.waitForPage();
fleetBundleNsMappingsListPage.baseResourceList().masthead().title()
.should('contain', 'BundleNamespaceMappings');
headerPo.selectWorkspace(defaultWorkspace);
fleetBundleNsMappingsPage.sharedComponents().baseResourceList().masthead().createYaml();
fleetBundleNsMappingsPage.createMappingForm().mastheadTitle().then((title) => {
fleetBundleNsMappingsListPage.baseResourceList().masthead().createYaml();
fleetBundleNsMappingCreateEditPage.mastheadTitle().then((title) => {
expect(title.replace(/\s+/g, ' ')).to.contain('BundleNamespaceMapping: Create');
});
fleetBundleNsMappingsPage.createMappingForm().waitForPage('as=yaml');
fleetBundleNsMappingsPage.sharedComponents().resourceDetail().resourceYaml().codeMirror()
fleetBundleNsMappingCreateEditPage.waitForPage('as=yaml');
fleetBundleNsMappingCreateEditPage.resourceDetail().resourceYaml().codeMirror()
.value()
.then((val) => {
// convert yaml into json to update values
@ -44,34 +46,36 @@ describe('Bundle Namespace Mappings', { testIsolation: 'off', tags: ['@fleet', '
json.metadata.name = customMappingName;
fleetBundleNsMappingsPage.sharedComponents().resourceDetail().resourceYaml().codeMirror()
fleetBundleNsMappingCreateEditPage.resourceDetail().resourceYaml().codeMirror()
.set(jsyaml.dump(json));
});
fleetBundleNsMappingsPage.sharedComponents().resourceDetail().resourceYaml().saveOrCreate()
fleetBundleNsMappingCreateEditPage.resourceDetail().resourceYaml().saveOrCreate()
.click();
cy.wait('@createMapping').then(({ response }) => {
expect(response?.statusCode).to.eq(201);
removeMappings = true;
mappingsNameList.push(customMappingName);
});
fleetBundleNsMappingsPage.waitForPage();
fleetBundleNsMappingsPage.sharedComponents().list().rowWithName(customMappingName).checkVisible();
fleetBundleNsMappingsListPage.waitForPage();
fleetBundleNsMappingsListPage.list().rowWithName(customMappingName).checkVisible();
});
// Skipping until issue resolved: https://github.com/rancher/dashboard/issues/13990
it.skip('can Edit Config', () => {
const fleetBundleNsMappingCreateEditPage = new FleetBundleNsMappingCreateEditPo(defaultWorkspace, customMappingName);
cy.intercept('PUT', `/v1/fleet.cattle.io.bundlenamespacemappings/${ defaultWorkspace }/${ customMappingName }`).as('editMapping');
fleetBundleNsMappingsPage.goTo();
fleetBundleNsMappingsPage.waitForPage();
fleetBundleNsMappingsPage.sharedComponents().list().actionMenu(customMappingName).getMenuItem('Edit YAML')
fleetBundleNsMappingsListPage.goTo();
fleetBundleNsMappingsListPage.waitForPage();
fleetBundleNsMappingsListPage.list().actionMenu(customMappingName).getMenuItem('Edit YAML')
.click();
fleetBundleNsMappingsPage.createMappingForm(defaultWorkspace, customMappingName).waitForPage('mode=edit&as=yaml');
fleetBundleNsMappingsPage.createMappingForm().mastheadTitle().then((title) => {
fleetBundleNsMappingCreateEditPage.waitForPage('mode=edit&as=yaml');
fleetBundleNsMappingCreateEditPage.mastheadTitle().then((title) => {
expect(title.replace(/\s+/g, ' ')).to.contain(`BundleNamespaceMapping: ${ customMappingName }`);
});
fleetBundleNsMappingsPage.sharedComponents().resourceDetail().resourceYaml().codeMirror()
fleetBundleNsMappingCreateEditPage.resourceDetail().resourceYaml().codeMirror()
.value()
.then((val) => {
// convert yaml into json to update values
@ -79,30 +83,32 @@ describe('Bundle Namespace Mappings', { testIsolation: 'off', tags: ['@fleet', '
json.metadata.namespace = localWorkspace;
fleetBundleNsMappingsPage.sharedComponents().resourceDetail().resourceYaml().codeMirror()
fleetBundleNsMappingCreateEditPage.resourceDetail().resourceYaml().codeMirror()
.set(jsyaml.dump(json));
});
fleetBundleNsMappingsPage.sharedComponents().resourceDetail().resourceYaml().saveOrCreate()
fleetBundleNsMappingCreateEditPage.resourceDetail().resourceYaml().saveOrCreate()
.click();
cy.wait('@editMapping').then(({ response }) => {
expect(response?.statusCode).to.eq(200);
expect(response?.body.metadata.namespace).equals(localWorkspace);
});
fleetBundleNsMappingsPage.waitForPage();
fleetBundleNsMappingsListPage.waitForPage();
});
it('can clone a bundle namespace mapping', () => {
const fleetBundleNsMappingCreateEditPage = new FleetBundleNsMappingCreateEditPo(defaultWorkspace, customMappingName);
cy.intercept('POST', '/v1/fleet.cattle.io.bundlenamespacemappings').as('cloneMapping');
fleetBundleNsMappingsPage.goTo();
fleetBundleNsMappingsPage.waitForPage();
fleetBundleNsMappingsPage.sharedComponents().list().actionMenu(customMappingName).getMenuItem('Clone')
fleetBundleNsMappingsListPage.goTo();
fleetBundleNsMappingsListPage.waitForPage();
fleetBundleNsMappingsListPage.list().actionMenu(customMappingName).getMenuItem('Clone')
.click();
fleetBundleNsMappingsPage.createMappingForm(defaultWorkspace, customMappingName).waitForPage('mode=clone&as=yaml');
fleetBundleNsMappingsPage.createMappingForm().mastheadTitle().then((title) => {
fleetBundleNsMappingCreateEditPage.waitForPage('mode=clone&as=yaml');
fleetBundleNsMappingCreateEditPage.mastheadTitle().then((title) => {
expect(title.replace(/\s+/g, ' ')).to.contain(`BundleNamespaceMapping: Clone from ${ customMappingName }`);
});
fleetBundleNsMappingsPage.sharedComponents().resourceDetail().resourceYaml().codeMirror()
fleetBundleNsMappingCreateEditPage.resourceDetail().resourceYaml().codeMirror()
.value()
.then((val) => {
// convert yaml into json to update values
@ -110,25 +116,25 @@ describe('Bundle Namespace Mappings', { testIsolation: 'off', tags: ['@fleet', '
json.metadata.name = `${ customMappingName }-clone`;
fleetBundleNsMappingsPage.sharedComponents().resourceDetail().resourceYaml().codeMirror()
fleetBundleNsMappingCreateEditPage.resourceDetail().resourceYaml().codeMirror()
.set(jsyaml.dump(json));
});
fleetBundleNsMappingsPage.sharedComponents().resourceDetail().resourceYaml().saveOrCreate()
fleetBundleNsMappingCreateEditPage.resourceDetail().resourceYaml().saveOrCreate()
.click();
cy.wait('@cloneMapping').then(({ response }) => {
expect(response?.statusCode).to.eq(201);
});
fleetBundleNsMappingsPage.waitForPage();
fleetBundleNsMappingsPage.sharedComponents().list().rowWithName(`${ customMappingName }-clone`).checkVisible();
fleetBundleNsMappingsListPage.waitForPage();
fleetBundleNsMappingsListPage.list().rowWithName(`${ customMappingName }-clone`).checkVisible();
});
it('can Download YAML', () => {
cy.deleteDownloadsFolder();
fleetBundleNsMappingsPage.goTo();
fleetBundleNsMappingsPage.waitForPage();
fleetBundleNsMappingsPage.sharedComponents().list().actionMenu(customMappingName).getMenuItem('Download YAML')
fleetBundleNsMappingsListPage.goTo();
fleetBundleNsMappingsListPage.waitForPage();
fleetBundleNsMappingsListPage.list().actionMenu(customMappingName).getMenuItem('Download YAML')
.click();
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', () => {
fleetBundleNsMappingsPage.goTo();
fleetBundleNsMappingsPage.waitForPage();
fleetBundleNsMappingsPage.sharedComponents().list().actionMenu(`${ customMappingName }-clone`).getMenuItem('Delete')
fleetBundleNsMappingsListPage.goTo();
fleetBundleNsMappingsListPage.waitForPage();
fleetBundleNsMappingsListPage.list().actionMenu(`${ customMappingName }-clone`).getMenuItem('Delete')
.click();
fleetBundleNsMappingsPage.sharedComponents().list().resourceTable().sortableTable()
fleetBundleNsMappingsListPage.list().resourceTable().sortableTable()
.rowNames('.col-link-detail')
.then((rows: any) => {
const promptRemove = new PromptRemove();
@ -156,10 +162,10 @@ describe('Bundle Namespace Mappings', { testIsolation: 'off', tags: ['@fleet', '
promptRemove.remove();
cy.wait('@deleteMapping');
fleetBundleNsMappingsPage.waitForPage();
fleetBundleNsMappingsPage.sharedComponents().list().resourceTable().sortableTable()
fleetBundleNsMappingsListPage.waitForPage();
fleetBundleNsMappingsListPage.list().resourceTable().sortableTable()
.checkRowCount(false, rows.length - 1);
fleetBundleNsMappingsPage.sharedComponents().list().resourceTable().sortableTable()
fleetBundleNsMappingsListPage.list().resourceTable().sortableTable()
.rowNames('.col-link-detail')
.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 FleetBundleDetailsPo from '@/cypress/e2e/po/detail/fleet/fleet.cattle.io.bundle.po';
import { FleetBundlesListPagePo, FleetBundleDetailsPo, FleetBundlesCreateEditPo } from '@/cypress/e2e/po/pages/fleet/fleet.cattle.io.bundle.po';
import { HeaderPo } from '@/cypress/e2e/po/components/header.po';
import * as path from 'path';
import * as jsyaml from 'js-yaml';
@ -15,7 +14,7 @@ const bundlesNameList = [];
const downloadsFolder = Cypress.config('downloadsFolder');
describe('Bundles', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] }, () => {
const fleetBundles = new FleetBundlesListPagePo();
const fleetBundlesListPage = new FleetBundlesListPagePo();
const headerPo = new HeaderPo();
describe('List', { tags: ['@vai', '@adminUser'] }, () => {
@ -25,13 +24,13 @@ describe('Bundles', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] }, ()
it('validate bundles table in empty state', () => {
FleetBundlesListPagePo.navTo();
fleetBundles.waitForPage();
fleetBundlesListPage.waitForPage();
headerPo.selectWorkspace(defaultWorkspace);
// check table headers
const expectedHeaders = ['State', 'Name', 'Deployments', 'Age'];
fleetBundles.sharedComponents().list().resourceTable().sortableTable()
fleetBundlesListPage.list().resourceTable().sortableTable()
.tableHeaderRow()
.within('.table-header-container .content')
.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', () => {
FleetBundlesListPagePo.navTo();
fleetBundles.waitForPage();
fleetBundlesListPage.waitForPage();
headerPo.selectWorkspace(localWorkspace);
// check table headers
const expectedHeaders = ['State', 'Name', 'Deployments', 'Age'];
fleetBundles.sharedComponents().list().resourceTable().sortableTable()
fleetBundlesListPage.list().resourceTable().sortableTable()
.tableHeaderRow()
.within('.table-header-container .content')
.each((el, i) => {
@ -55,16 +54,16 @@ describe('Bundles', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] }, ()
});
// 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
const expectedHeadersDetailsViewEvents = ['State', 'Cluster', 'API Version', 'Kind', 'Name', 'Namespace'];
fleetBundleeDetailsPage.list().resourceTable().sortableTable()
fleetBundlesDetailsPage.resourcesList().sortableTable()
.tableHeaderRow()
.within('.table-header-container .content')
.each((el, i) => {
@ -83,18 +82,19 @@ describe('Bundles', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] }, ()
it('can create a bundle', () => {
cy.intercept('POST', '/v1/fleet.cattle.io.bundles').as('createBundle');
const fleetBundleCreateEditPage = new FleetBundlesCreateEditPo();
fleetBundles.goTo();
fleetBundles.waitForPage();
fleetBundles.sharedComponents().baseResourceList().masthead().title()
fleetBundlesListPage.goTo();
fleetBundlesListPage.waitForPage();
fleetBundlesListPage.baseResourceList().masthead().title()
.should('contain', 'Bundles');
headerPo.selectWorkspace(localWorkspace);
fleetBundles.sharedComponents().baseResourceList().masthead().createYaml();
fleetBundles.createBundlesForm().waitForPage('as=yaml');
fleetBundles.createBundlesForm().mastheadTitle().then((title) => {
fleetBundlesListPage.baseResourceList().masthead().createYaml();
fleetBundleCreateEditPage.waitForPage('as=yaml');
fleetBundleCreateEditPage.mastheadTitle().then((title) => {
expect(title.replace(/\s+/g, ' ')).to.contain('Bundle: Create');
});
fleetBundles.sharedComponents().resourceDetail().resourceYaml().codeMirror()
fleetBundleCreateEditPage.resourceDetail().resourceYaml().codeMirror()
.value()
.then((val) => {
// 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));
});
fleetBundles.sharedComponents().resourceDetail().resourceYaml().saveOrCreate()
fleetBundleCreateEditPage.resourceDetail().resourceYaml().saveOrCreate()
.click();
cy.wait('@createBundle').then(({ response }) => {
expect(response?.statusCode).to.eq(201);
removeBundle = true;
bundlesNameList.push(customBundleName);
});
fleetBundles.waitForPage();
fleetBundles.sharedComponents().list().rowWithName(customBundleName).checkVisible();
fleetBundlesListPage.waitForPage();
fleetBundlesListPage.list().rowWithName(customBundleName).checkVisible();
// 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
it.skip('can Edit Config', () => {
const fleetBundleCreateEditPage = new FleetBundlesCreateEditPo(localWorkspace, customBundleName);
cy.intercept('PUT', `/v1/fleet.cattle.io.bundles/${ localWorkspace }/${ customBundleName }`).as('editBundle');
fleetBundles.goTo();
fleetBundles.waitForPage();
fleetBundlesListPage.goTo();
fleetBundlesListPage.waitForPage();
headerPo.selectWorkspace(localWorkspace);
fleetBundles.sharedComponents().list().actionMenu(customBundleName).getMenuItem('Edit YAML')
fleetBundlesListPage.list().actionMenu(customBundleName).getMenuItem('Edit YAML')
.click();
fleetBundles.createBundlesForm(localWorkspace, customBundleName).waitForPage('mode=edit&as=yaml');
fleetBundles.createBundlesForm().mastheadTitle().then((title) => {
fleetBundleCreateEditPage.waitForPage('mode=edit&as=yaml');
fleetBundleCreateEditPage.mastheadTitle().then((title) => {
expect(title.replace(/\s+/g, ' ')).to.contain(`Bundle: ${ customBundleName }`);
});
fleetBundles.sharedComponents().resourceDetail().resourceYaml().codeMirror()
fleetBundleCreateEditPage.resourceDetail().resourceYaml().codeMirror()
.value()
.then((val) => {
// convert yaml into json to update values
@ -158,31 +160,33 @@ describe('Bundles', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] }, ()
json.metadata.namespace = localWorkspace;
fleetBundles.sharedComponents().resourceDetail().resourceYaml().codeMirror()
fleetBundleCreateEditPage.resourceDetail().resourceYaml().codeMirror()
.set(jsyaml.dump(json));
});
fleetBundles.sharedComponents().resourceDetail().resourceYaml().saveOrCreate()
fleetBundleCreateEditPage.resourceDetail().resourceYaml().saveOrCreate()
.click();
cy.wait('@editBundle').then(({ response }) => {
expect(response?.statusCode).to.eq(200);
expect(response?.body.metadata.namespace).equals(localWorkspace);
});
fleetBundles.waitForPage();
fleetBundlesListPage.waitForPage();
});
it('can clone a bundle', () => {
const fleetBundleCreateEditPage = new FleetBundlesCreateEditPo(localWorkspace, customBundleName);
cy.intercept('POST', '/v1/fleet.cattle.io.bundles').as('cloneBundle');
fleetBundles.goTo();
fleetBundles.waitForPage();
fleetBundlesListPage.goTo();
fleetBundlesListPage.waitForPage();
headerPo.selectWorkspace(localWorkspace);
fleetBundles.sharedComponents().list().actionMenu(customBundleName).getMenuItem('Clone')
fleetBundlesListPage.list().actionMenu(customBundleName).getMenuItem('Clone')
.click();
fleetBundles.createBundlesForm(localWorkspace, customBundleName).waitForPage('mode=clone&as=yaml');
fleetBundles.createBundlesForm().mastheadTitle().then((title) => {
fleetBundleCreateEditPage.waitForPage('mode=clone&as=yaml');
fleetBundleCreateEditPage.mastheadTitle().then((title) => {
expect(title.replace(/\s+/g, ' ')).to.contain(`Bundle: Clone from ${ customBundleName }`);
});
fleetBundles.sharedComponents().resourceDetail().resourceYaml().codeMirror()
fleetBundleCreateEditPage.resourceDetail().resourceYaml().codeMirror()
.value()
.then((val) => {
// convert yaml into json to update values
@ -190,28 +194,28 @@ describe('Bundles', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] }, ()
json.metadata.name = `${ customBundleName }-clone`;
fleetBundles.sharedComponents().resourceDetail().resourceYaml().codeMirror()
fleetBundleCreateEditPage.resourceDetail().resourceYaml().codeMirror()
.set(jsyaml.dump(json));
});
fleetBundles.sharedComponents().resourceDetail().resourceYaml().saveOrCreate()
fleetBundleCreateEditPage.resourceDetail().resourceYaml().saveOrCreate()
.click();
cy.wait('@cloneBundle').then(({ response }) => {
expect(response?.statusCode).to.eq(201);
});
fleetBundles.waitForPage();
fleetBundles.sharedComponents().list().rowWithName(`${ customBundleName }-clone`).checkVisible();
fleetBundlesListPage.waitForPage();
fleetBundlesListPage.list().rowWithName(`${ customBundleName }-clone`).checkVisible();
// 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', () => {
cy.deleteDownloadsFolder();
fleetBundles.goTo();
fleetBundles.waitForPage();
fleetBundlesListPage.goTo();
fleetBundlesListPage.waitForPage();
headerPo.selectWorkspace(localWorkspace);
fleetBundles.sharedComponents().list().actionMenu(customBundleName).getMenuItem('Download YAML')
fleetBundlesListPage.list().actionMenu(customBundleName).getMenuItem('Download YAML')
.click();
const downloadedFilename = path.join(downloadsFolder, `${ customBundleName }.yaml`);
@ -226,12 +230,12 @@ describe('Bundles', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] }, ()
});
it('can delete a bundle', () => {
fleetBundles.goTo();
fleetBundles.waitForPage();
fleetBundlesListPage.goTo();
fleetBundlesListPage.waitForPage();
headerPo.selectWorkspace(localWorkspace);
fleetBundles.sharedComponents().list().actionMenu(`${ customBundleName }-clone`).getMenuItem('Delete')
fleetBundlesListPage.list().actionMenu(`${ customBundleName }-clone`).getMenuItem('Delete')
.click();
fleetBundles.sharedComponents().list().resourceTable().sortableTable()
fleetBundlesListPage.list().resourceTable().sortableTable()
.rowNames('.col-link-detail')
.then((rows: any) => {
const promptRemove = new PromptRemove();
@ -240,10 +244,10 @@ describe('Bundles', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] }, ()
promptRemove.remove();
cy.wait('@deleteBundle');
fleetBundles.waitForPage();
fleetBundles.sharedComponents().list().resourceTable().sortableTable()
fleetBundlesListPage.waitForPage();
fleetBundlesListPage.list().resourceTable().sortableTable()
.checkRowCount(false, rows.length - 1);
fleetBundles.sharedComponents().list().resourceTable().sortableTable()
fleetBundlesListPage.list().resourceTable().sortableTable()
.rowNames('.col-link-detail')
.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 { clusterRegistrationTokensNoData, generateclusterRegistrationTokensDataSmall } from '@/cypress/e2e/blueprints/fleet/cluster-registration-tokens-get';
import * as path from 'path';
@ -13,7 +13,8 @@ const tokenNameList = [];
const downloadsFolder = Cypress.config('downloadsFolder');
describe('Cluster Registration Tokens', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] }, () => {
const fleetTokensPage = new FleetClusterRegistrationTokenListPagePo();
const fleetTokensListPage = new FleetClusterRegistrationTokenListPagePo();
const headerPo = new HeaderPo();
describe('CRUD', { tags: ['@fleet', '@adminUser'] }, () => {
@ -25,19 +26,21 @@ describe('Cluster Registration Tokens', { testIsolation: 'off', tags: ['@fleet',
});
it('can create a cluster registration token', () => {
const fleetTokenCreateEditPage = new FleetTokensCreateEditPo();
cy.intercept('POST', '/v1/fleet.cattle.io.clusterregistrationtokens').as('createToken');
fleetTokensPage.goTo();
fleetTokensPage.waitForPage();
fleetTokensPage.sharedComponents().baseResourceList().masthead().title()
fleetTokensListPage.goTo();
fleetTokensListPage.waitForPage();
fleetTokensListPage.baseResourceList().masthead().title()
.should('contain', 'Cluster Registration Tokens');
headerPo.selectWorkspace(defaultWorkspace);
fleetTokensPage.sharedComponents().baseResourceList().masthead().createYaml();
fleetTokensPage.createTokenForm().waitForPage('as=yaml');
fleetTokensPage.createTokenForm().mastheadTitle().then((title) => {
fleetTokensListPage.baseResourceList().masthead().createYaml();
fleetTokenCreateEditPage.waitForPage('as=yaml');
fleetTokenCreateEditPage.mastheadTitle().then((title) => {
expect(title.replace(/\s+/g, ' ')).to.contain('Cluster Registration Token: Create');
});
fleetTokensPage.sharedComponents().resourceDetail().resourceYaml().codeMirror()
fleetTokenCreateEditPage.resourceDetail().resourceYaml().codeMirror()
.value()
.then((val) => {
// convert yaml into json to update values
@ -45,34 +48,36 @@ describe('Cluster Registration Tokens', { testIsolation: 'off', tags: ['@fleet',
json.metadata.name = customTokenName;
fleetTokensPage.sharedComponents().resourceDetail().resourceYaml().codeMirror()
fleetTokenCreateEditPage.resourceDetail().resourceYaml().codeMirror()
.set(jsyaml.dump(json));
});
fleetTokensPage.sharedComponents().resourceDetail().resourceYaml().saveOrCreate()
fleetTokenCreateEditPage.resourceDetail().resourceYaml().saveOrCreate()
.click();
cy.wait('@createToken').then(({ response }) => {
expect(response?.statusCode).to.eq(201);
removeToken = true;
tokenNameList.push(customTokenName);
});
fleetTokensPage.waitForPage();
fleetTokensPage.sharedComponents().list().rowWithName(customTokenName).checkVisible();
fleetTokensListPage.waitForPage();
fleetTokensListPage.list().rowWithName(customTokenName).checkVisible();
});
// Skipping until issue resolved: https://github.com/rancher/dashboard/issues/13990
it.skip('can Edit Config', () => {
const fleetTokenCreateEditPage = new FleetTokensCreateEditPo(defaultWorkspace, customTokenName);
cy.intercept('PUT', `/v1/fleet.cattle.io.clusterregistrationtokens/${ defaultWorkspace }/${ customTokenName }`).as('editToken');
fleetTokensPage.goTo();
fleetTokensPage.waitForPage();
fleetTokensPage.sharedComponents().list().actionMenu(customTokenName).getMenuItem('Edit YAML')
fleetTokensListPage.goTo();
fleetTokensListPage.waitForPage();
fleetTokensListPage.list().actionMenu(customTokenName).getMenuItem('Edit YAML')
.click();
fleetTokensPage.createTokenForm(defaultWorkspace, customTokenName).waitForPage('mode=edit&as=yaml');
fleetTokensPage.createTokenForm().mastheadTitle().then((title) => {
fleetTokenCreateEditPage.waitForPage('mode=edit&as=yaml');
fleetTokenCreateEditPage.mastheadTitle().then((title) => {
expect(title.replace(/\s+/g, ' ')).to.contain(`Cluster Registration Token: ${ customTokenName }`);
});
fleetTokensPage.sharedComponents().resourceDetail().resourceYaml().codeMirror()
fleetTokenCreateEditPage.resourceDetail().resourceYaml().codeMirror()
.value()
.then((val) => {
// convert yaml into json to update values
@ -80,30 +85,32 @@ describe('Cluster Registration Tokens', { testIsolation: 'off', tags: ['@fleet',
json.metadata.namespace = localWorkspace;
fleetTokensPage.sharedComponents().resourceDetail().resourceYaml().codeMirror()
fleetTokenCreateEditPage.resourceDetail().resourceYaml().codeMirror()
.set(jsyaml.dump(json));
});
fleetTokensPage.sharedComponents().resourceDetail().resourceYaml().saveOrCreate()
fleetTokenCreateEditPage.resourceDetail().resourceYaml().saveOrCreate()
.click();
cy.wait('@editToken').then(({ response }) => {
expect(response?.statusCode).to.eq(200);
expect(response?.body.metadata.namespace).equals(localWorkspace);
});
fleetTokensPage.waitForPage();
fleetTokensListPage.waitForPage();
});
it('can clone a cluster registration token', () => {
const fleetTokenCreateEditPage = new FleetTokensCreateEditPo(defaultWorkspace, customTokenName);
cy.intercept('POST', '/v1/fleet.cattle.io.clusterregistrationtokens').as('cloneToken');
fleetTokensPage.goTo();
fleetTokensPage.waitForPage();
fleetTokensPage.sharedComponents().list().actionMenu(customTokenName).getMenuItem('Clone')
fleetTokensListPage.goTo();
fleetTokensListPage.waitForPage();
fleetTokensListPage.list().actionMenu(customTokenName).getMenuItem('Clone')
.click();
fleetTokensPage.createTokenForm(defaultWorkspace, customTokenName).waitForPage('mode=clone&as=yaml');
fleetTokensPage.createTokenForm().mastheadTitle().then((title) => {
fleetTokenCreateEditPage.waitForPage('mode=clone&as=yaml');
fleetTokenCreateEditPage.mastheadTitle().then((title) => {
expect(title.replace(/\s+/g, ' ')).to.contain(`Cluster Registration Token: Clone from ${ customTokenName }`);
});
fleetTokensPage.sharedComponents().resourceDetail().resourceYaml().codeMirror()
fleetTokenCreateEditPage.resourceDetail().resourceYaml().codeMirror()
.value()
.then((val) => {
// convert yaml into json to update values
@ -111,25 +118,25 @@ describe('Cluster Registration Tokens', { testIsolation: 'off', tags: ['@fleet',
json.metadata.name = `${ customTokenName }-clone`;
fleetTokensPage.sharedComponents().resourceDetail().resourceYaml().codeMirror()
fleetTokenCreateEditPage.resourceDetail().resourceYaml().codeMirror()
.set(jsyaml.dump(json));
});
fleetTokensPage.sharedComponents().resourceDetail().resourceYaml().saveOrCreate()
fleetTokenCreateEditPage.resourceDetail().resourceYaml().saveOrCreate()
.click();
cy.wait('@cloneToken').then(({ response }) => {
expect(response?.statusCode).to.eq(201);
});
fleetTokensPage.waitForPage();
fleetTokensPage.sharedComponents().list().rowWithName(`${ customTokenName }-clone`).checkVisible();
fleetTokensListPage.waitForPage();
fleetTokensListPage.list().rowWithName(`${ customTokenName }-clone`).checkVisible();
});
it('can Download YAML', () => {
cy.deleteDownloadsFolder();
fleetTokensPage.goTo();
fleetTokensPage.waitForPage();
fleetTokensPage.sharedComponents().list().actionMenu(customTokenName).getMenuItem('Download YAML')
fleetTokensListPage.goTo();
fleetTokensListPage.waitForPage();
fleetTokensListPage.list().actionMenu(customTokenName).getMenuItem('Download YAML')
.click();
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', () => {
fleetTokensPage.goTo();
fleetTokensPage.waitForPage();
fleetTokensPage.sharedComponents().list().actionMenu(`${ customTokenName }-clone`).getMenuItem('Delete')
fleetTokensListPage.goTo();
fleetTokensListPage.waitForPage();
fleetTokensListPage.list().actionMenu(`${ customTokenName }-clone`).getMenuItem('Delete')
.click();
fleetTokensPage.sharedComponents().list().resourceTable().sortableTable()
fleetTokensListPage.list().resourceTable().sortableTable()
.rowNames('.col-link-detail')
.then((rows: any) => {
const promptRemove = new PromptRemove();
@ -157,10 +164,10 @@ describe('Cluster Registration Tokens', { testIsolation: 'off', tags: ['@fleet',
promptRemove.remove();
cy.wait('@deleteToken');
fleetTokensPage.waitForPage();
fleetTokensPage.sharedComponents().list().resourceTable().sortableTable()
fleetTokensListPage.waitForPage();
fleetTokensListPage.list().resourceTable().sortableTable()
.checkRowCount(false, rows.length - 1);
fleetTokensPage.sharedComponents().list().resourceTable().sortableTable()
fleetTokensListPage.list().resourceTable().sortableTable()
.rowNames('.col-link-detail')
.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', () => {
clusterRegistrationTokensNoData();
fleetTokensPage.goTo();
fleetTokensPage.waitForPage();
fleetTokensListPage.goTo();
fleetTokensListPage.waitForPage();
cy.wait('@clusterRegistrationTokensNoData');
const expectedHeaders = ['State', 'Name', 'Namespace', 'Secret-Name'];
fleetTokensPage.sharedComponents().list().resourceTable().sortableTable()
fleetTokensListPage.list().resourceTable().sortableTable()
.tableHeaderRow()
.get('.table-header-container .content')
.each((el, i) => {
expect(el.text().trim()).to.eq(expectedHeaders[i]);
});
fleetTokensPage.sharedComponents().list().resourceTable().sortableTable()
fleetTokensListPage.list().resourceTable().sortableTable()
.checkRowCount(true, 1);
});
it('validate cluster registration tokens table', () => {
generateclusterRegistrationTokensDataSmall();
FleetClusterRegistrationTokenListPagePo.navTo();
fleetTokensPage.waitForPage();
fleetTokensListPage.waitForPage();
headerPo.selectWorkspace(defaultWorkspace);
// check table headers
const expectedHeaders = ['State', 'Name', 'Namespace', 'Secret-Name'];
fleetTokensPage.sharedComponents().list().resourceTable().sortableTable()
fleetTokensListPage.list().resourceTable().sortableTable()
.tableHeaderRow()
.within('.table-header-container .content')
.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 * as path from 'path';
import * as jsyaml from 'js-yaml';
@ -12,7 +12,7 @@ const restrictionNameList = [];
const downloadsFolder = Cypress.config('downloadsFolder');
describe('GitRepo Restrictions', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] }, () => {
const fleetRestrictionsPage = new FleetGitRepoRestrictionListPagePo();
const fleetRestrictionsListPage = new FleetGitRepoRestrictionListPagePo();
const headerPo = new HeaderPo();
describe('CRUD', { tags: ['@fleet', '@adminUser'] }, () => {
@ -24,19 +24,21 @@ describe('GitRepo Restrictions', { testIsolation: 'off', tags: ['@fleet', '@admi
});
it('can create a gitrepo restriction', () => {
const fleetRestrictionCreateEditPage = new FleetRestrictionCreateEditPo();
cy.intercept('POST', '/v1/fleet.cattle.io.gitreporestrictions').as('createRestriction');
fleetRestrictionsPage.goTo();
fleetRestrictionsPage.waitForPage();
fleetRestrictionsPage.sharedComponents().baseResourceList().masthead().title()
fleetRestrictionsListPage.goTo();
fleetRestrictionsListPage.waitForPage();
fleetRestrictionsListPage.baseResourceList().masthead().title()
.should('contain', 'GitRepoRestrictions');
headerPo.selectWorkspace(defaultWorkspace);
fleetRestrictionsPage.sharedComponents().baseResourceList().masthead().createYaml();
fleetRestrictionsPage.createRestrictionForm().waitForPage('as=yaml');
fleetRestrictionsPage.createRestrictionForm().mastheadTitle().then((title) => {
fleetRestrictionsListPage.baseResourceList().masthead().createYaml();
fleetRestrictionCreateEditPage.waitForPage('as=yaml');
fleetRestrictionCreateEditPage.mastheadTitle().then((title) => {
expect(title.replace(/\s+/g, ' ')).to.contain('GitRepoRestriction: Create');
});
fleetRestrictionsPage.sharedComponents().resourceDetail().resourceYaml().codeMirror()
fleetRestrictionCreateEditPage.resourceDetail().resourceYaml().codeMirror()
.value()
.then((val) => {
// convert yaml into json to update values
@ -44,34 +46,36 @@ describe('GitRepo Restrictions', { testIsolation: 'off', tags: ['@fleet', '@admi
json.metadata.name = customRestrictionName;
fleetRestrictionsPage.sharedComponents().resourceDetail().resourceYaml().codeMirror()
fleetRestrictionCreateEditPage.resourceDetail().resourceYaml().codeMirror()
.set(jsyaml.dump(json));
});
fleetRestrictionsPage.sharedComponents().resourceDetail().resourceYaml().saveOrCreate()
fleetRestrictionCreateEditPage.resourceDetail().resourceYaml().saveOrCreate()
.click();
cy.wait('@createRestriction').then(({ response }) => {
expect(response?.statusCode).to.eq(201);
removeRestriction = true;
restrictionNameList.push(customRestrictionName);
});
fleetRestrictionsPage.waitForPage();
fleetRestrictionsPage.sharedComponents().list().rowWithName(customRestrictionName).checkVisible();
fleetRestrictionsListPage.waitForPage();
fleetRestrictionsListPage.list().rowWithName(customRestrictionName).checkVisible();
});
// Skipping until issue resolved: https://github.com/rancher/dashboard/issues/13990
it.skip('can Edit Config', () => {
const fleetRestrictionCreateEditPage = new FleetRestrictionCreateEditPo(defaultWorkspace, customRestrictionName);
cy.intercept('PUT', `/v1/fleet.cattle.io.gitreporestrictions/${ defaultWorkspace }/${ customRestrictionName }`).as('editRestriction');
fleetRestrictionsPage.goTo();
fleetRestrictionsPage.waitForPage();
fleetRestrictionsPage.sharedComponents().list().actionMenu(customRestrictionName).getMenuItem('Edit YAML')
fleetRestrictionsListPage.goTo();
fleetRestrictionsListPage.waitForPage();
fleetRestrictionsListPage.list().actionMenu(customRestrictionName).getMenuItem('Edit YAML')
.click();
fleetRestrictionsPage.createRestrictionForm(defaultWorkspace, customRestrictionName).waitForPage('mode=edit&as=yaml');
fleetRestrictionsPage.createRestrictionForm().mastheadTitle().then((title) => {
fleetRestrictionCreateEditPage.waitForPage('mode=edit&as=yaml');
fleetRestrictionCreateEditPage.mastheadTitle().then((title) => {
expect(title.replace(/\s+/g, ' ')).to.contain(`GitRepoRestriction: ${ customRestrictionName }`);
});
fleetRestrictionsPage.sharedComponents().resourceDetail().resourceYaml().codeMirror()
fleetRestrictionCreateEditPage.resourceDetail().resourceYaml().codeMirror()
.value()
.then((val) => {
// convert yaml into json to update values
@ -79,30 +83,32 @@ describe('GitRepo Restrictions', { testIsolation: 'off', tags: ['@fleet', '@admi
json.metadata.namespace = localWorkspace;
fleetRestrictionsPage.sharedComponents().resourceDetail().resourceYaml().codeMirror()
fleetRestrictionCreateEditPage.resourceDetail().resourceYaml().codeMirror()
.set(jsyaml.dump(json));
});
fleetRestrictionsPage.sharedComponents().resourceDetail().resourceYaml().saveOrCreate()
fleetRestrictionCreateEditPage.resourceDetail().resourceYaml().saveOrCreate()
.click();
cy.wait('@editRestriction').then(({ response }) => {
expect(response?.statusCode).to.eq(200);
expect(response?.body.metadata.namespace).equals(localWorkspace);
});
fleetRestrictionsPage.waitForPage();
fleetRestrictionsListPage.waitForPage();
});
it('can clone a gitrepo restriction', () => {
const fleetRestrictionCreateEditPage = new FleetRestrictionCreateEditPo(defaultWorkspace, customRestrictionName);
cy.intercept('POST', '/v1/fleet.cattle.io.gitreporestrictions').as('cloneRestriction');
fleetRestrictionsPage.goTo();
fleetRestrictionsPage.waitForPage();
fleetRestrictionsPage.sharedComponents().list().actionMenu(customRestrictionName).getMenuItem('Clone')
fleetRestrictionsListPage.goTo();
fleetRestrictionsListPage.waitForPage();
fleetRestrictionsListPage.list().actionMenu(customRestrictionName).getMenuItem('Clone')
.click();
fleetRestrictionsPage.createRestrictionForm(defaultWorkspace, customRestrictionName).waitForPage('mode=clone&as=yaml');
fleetRestrictionsPage.createRestrictionForm().mastheadTitle().then((title) => {
fleetRestrictionCreateEditPage.waitForPage('mode=clone&as=yaml');
fleetRestrictionCreateEditPage.mastheadTitle().then((title) => {
expect(title.replace(/\s+/g, ' ')).to.contain(`GitRepoRestriction: Clone from ${ customRestrictionName }`);
});
fleetRestrictionsPage.sharedComponents().resourceDetail().resourceYaml().codeMirror()
fleetRestrictionCreateEditPage.resourceDetail().resourceYaml().codeMirror()
.value()
.then((val) => {
// convert yaml into json to update values
@ -110,25 +116,25 @@ describe('GitRepo Restrictions', { testIsolation: 'off', tags: ['@fleet', '@admi
json.metadata.name = `${ customRestrictionName }-clone`;
fleetRestrictionsPage.sharedComponents().resourceDetail().resourceYaml().codeMirror()
fleetRestrictionCreateEditPage.resourceDetail().resourceYaml().codeMirror()
.set(jsyaml.dump(json));
});
fleetRestrictionsPage.sharedComponents().resourceDetail().resourceYaml().saveOrCreate()
fleetRestrictionCreateEditPage.resourceDetail().resourceYaml().saveOrCreate()
.click();
cy.wait('@cloneRestriction').then(({ response }) => {
expect(response?.statusCode).to.eq(201);
});
fleetRestrictionsPage.waitForPage();
fleetRestrictionsPage.sharedComponents().list().rowWithName(`${ customRestrictionName }-clone`).checkVisible();
fleetRestrictionsListPage.waitForPage();
fleetRestrictionsListPage.list().rowWithName(`${ customRestrictionName }-clone`).checkVisible();
});
it('can Download YAML', () => {
cy.deleteDownloadsFolder();
fleetRestrictionsPage.goTo();
fleetRestrictionsPage.waitForPage();
fleetRestrictionsPage.sharedComponents().list().actionMenu(customRestrictionName).getMenuItem('Download YAML')
fleetRestrictionsListPage.goTo();
fleetRestrictionsListPage.waitForPage();
fleetRestrictionsListPage.list().actionMenu(customRestrictionName).getMenuItem('Download YAML')
.click();
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', () => {
fleetRestrictionsPage.goTo();
fleetRestrictionsPage.waitForPage();
fleetRestrictionsPage.sharedComponents().list().actionMenu(`${ customRestrictionName }-clone`).getMenuItem('Delete')
fleetRestrictionsListPage.goTo();
fleetRestrictionsListPage.waitForPage();
fleetRestrictionsListPage.list().actionMenu(`${ customRestrictionName }-clone`).getMenuItem('Delete')
.click();
fleetRestrictionsPage.sharedComponents().list().resourceTable().sortableTable()
fleetRestrictionsListPage.list().resourceTable().sortableTable()
.rowNames('.col-link-detail')
.then((rows: any) => {
const promptRemove = new PromptRemove();
@ -156,10 +162,10 @@ describe('GitRepo Restrictions', { testIsolation: 'off', tags: ['@fleet', '@admi
promptRemove.remove();
cy.wait('@deleteRestriction');
fleetRestrictionsPage.waitForPage();
fleetRestrictionsPage.sharedComponents().list().resourceTable().sortableTable()
fleetRestrictionsListPage.waitForPage();
fleetRestrictionsListPage.list().resourceTable().sortableTable()
.checkRowCount(false, rows.length - 1);
fleetRestrictionsPage.sharedComponents().list().resourceTable().sortableTable()
fleetRestrictionsListPage.list().resourceTable().sortableTable()
.rowNames('.col-link-detail')
.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 FleetWorkspaceDetailsPo from '@/cypress/e2e/po/detail/fleet/fleet.cattle.io.fleetworkspace.po';
import { FleetWorkspaceListPagePo, FleetWorkspaceCreateEditPo, FleetWorkspaceDetailsPo } from '@/cypress/e2e/po/pages/fleet/fleet.cattle.io.fleetworkspace.po';
import { generateFleetWorkspacesDataSmall } from '@/cypress/e2e/blueprints/fleet/workspaces-get';
import HomePagePo from '@/cypress/e2e/po/pages/home.po';
import SortableTablePo from '@/cypress/e2e/po/components/sortable-table.po';
@ -14,7 +13,8 @@ let customWorkspace = '';
const downloadsFolder = Cypress.config('downloadsFolder');
describe('Workspaces', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] }, () => {
const fleetWorkspacesPage = new FleetWorkspaceListPagePo();
const fleetWorkspacesListPage = new FleetWorkspaceListPagePo();
const headerPo = new HeaderPo();
before(() => {
@ -28,16 +28,19 @@ describe('Workspaces', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] },
let initialCount: number;
it('check table headers are available in list and details view', () => {
fleetWorkspacesPage.goTo();
fleetWorkspacesPage.waitForPage();
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().noRowsShouldNotExist();
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().filter(defaultWorkspace);
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().checkRowCount(false, 1);
fleetWorkspacesListPage.goTo();
fleetWorkspacesListPage.waitForPage();
fleetWorkspacesListPage.list().resourceTable().sortableTable()
.noRowsShouldNotExist();
fleetWorkspacesListPage.list().resourceTable().sortableTable()
.filter(defaultWorkspace);
fleetWorkspacesListPage.list().resourceTable().sortableTable()
.checkRowCount(false, 1);
// check table headers
const expectedHeaders = ['State', 'Name', 'Git Repos', 'Clusters', 'Cluster Groups', 'Age'];
fleetWorkspacesPage.sharedComponents().list().resourceTable().sortableTable()
fleetWorkspacesListPage.list().resourceTable().sortableTable()
.tableHeaderRow()
.within('.table-header-container .content')
.each((el, i) => {
@ -45,7 +48,7 @@ describe('Workspaces', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] },
});
// go to fleet workspaces details
fleetWorkspacesPage.sharedComponents().goToDetailsPage(defaultWorkspace);
fleetWorkspacesListPage.goToDetailsPage(defaultWorkspace);
const fleetWorkspaceDetailsPage = new FleetWorkspaceDetailsPo(defaultWorkspace);
@ -54,7 +57,7 @@ describe('Workspaces', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] },
// check table headers
const expectedHeadersDetailsViewEvents = ['Type', 'Reason', 'Updated', 'Message'];
fleetWorkspaceDetailsPage.recentEventsList().resourceTable().sortableTable()
fleetWorkspaceDetailsPage.recentEventsList().sortableTable()
.tableHeaderRow()
.within('.table-header-container .content')
.each((el, i) => {
@ -67,14 +70,14 @@ describe('Workspaces', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] },
// check table headers
const expectedHeadersDetailsViewResources = ['State', 'Type', 'Name', 'Namespace'];
fleetWorkspaceDetailsPage.relatedResourcesList(1).resourceTable().sortableTable()
fleetWorkspaceDetailsPage.relatedResourcesList(1).sortableTable()
.tableHeaderRow()
.within('.table-header-container .content')
.each((el, i) => {
expect(el.text().trim()).to.eq(expectedHeadersDetailsViewResources[i]);
});
fleetWorkspaceDetailsPage.relatedResourcesList(2).resourceTable().sortableTable()
fleetWorkspaceDetailsPage.relatedResourcesList(2).sortableTable()
.tableHeaderRow()
.within('.table-header-container .content')
.each((el, i) => {
@ -125,100 +128,121 @@ describe('Workspaces', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] },
const count = resp.body.count;
FleetWorkspaceListPagePo.navTo();
fleetWorkspacesPage.waitForPage();
fleetWorkspacesListPage.waitForPage();
// pagination is visible
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().pagination()
fleetWorkspacesListPage.list().resourceTable().sortableTable()
.pagination()
.checkVisible();
// basic checks on navigation buttons
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().pagination()
fleetWorkspacesListPage.list().resourceTable().sortableTable()
.pagination()
.beginningButton()
.isDisabled();
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().pagination()
fleetWorkspacesListPage.list().resourceTable().sortableTable()
.pagination()
.leftButton()
.isDisabled();
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().pagination()
fleetWorkspacesListPage.list().resourceTable().sortableTable()
.pagination()
.rightButton()
.isEnabled();
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().pagination()
fleetWorkspacesListPage.list().resourceTable().sortableTable()
.pagination()
.endButton()
.isEnabled();
// check text before navigation
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().pagination()
fleetWorkspacesListPage.list().resourceTable().sortableTable()
.pagination()
.paginationText()
.then((el) => {
expect(el.trim()).to.eq(`1 - 10 of ${ count } Workspaces`);
});
// navigate to next page - right button
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().pagination()
fleetWorkspacesListPage.list().resourceTable().sortableTable()
.pagination()
.rightButton()
.click();
// check text and buttons after navigation
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().pagination()
fleetWorkspacesListPage.list().resourceTable().sortableTable()
.pagination()
.paginationText()
.then((el) => {
expect(el.trim()).to.eq(`11 - 20 of ${ count } Workspaces`);
});
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().pagination()
fleetWorkspacesListPage.list().resourceTable().sortableTable()
.pagination()
.beginningButton()
.isEnabled();
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().pagination()
fleetWorkspacesListPage.list().resourceTable().sortableTable()
.pagination()
.leftButton()
.isEnabled();
// navigate to first page - left button
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().pagination()
fleetWorkspacesListPage.list().resourceTable().sortableTable()
.pagination()
.leftButton()
.click();
// check text and buttons after navigation
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().pagination()
fleetWorkspacesListPage.list().resourceTable().sortableTable()
.pagination()
.paginationText()
.then((el) => {
expect(el.trim()).to.eq(`1 - 10 of ${ count } Workspaces`);
});
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().pagination()
fleetWorkspacesListPage.list().resourceTable().sortableTable()
.pagination()
.beginningButton()
.isDisabled();
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().pagination()
fleetWorkspacesListPage.list().resourceTable().sortableTable()
.pagination()
.leftButton()
.isDisabled();
// navigate to last page - end button
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().pagination()
fleetWorkspacesListPage.list().resourceTable().sortableTable()
.pagination()
.endButton()
.scrollIntoView()
.click();
// 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
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().pagination()
fleetWorkspacesListPage.list().resourceTable().sortableTable()
.pagination()
.paginationText()
.then((el) => {
expect(el.trim()).to.eq(`21 - ${ count } of ${ count } Workspaces`);
});
// navigate to first page - beginning button
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().pagination()
fleetWorkspacesListPage.list().resourceTable().sortableTable()
.pagination()
.beginningButton()
.click();
// check text and buttons after navigation
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().pagination()
fleetWorkspacesListPage.list().resourceTable().sortableTable()
.pagination()
.paginationText()
.then((el) => {
expect(el.trim()).to.eq(`1 - 10 of ${ count } Workspaces`);
});
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().pagination()
fleetWorkspacesListPage.list().resourceTable().sortableTable()
.pagination()
.beginningButton()
.isDisabled();
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().pagination()
fleetWorkspacesListPage.list().resourceTable().sortableTable()
.pagination()
.leftButton()
.isDisabled();
});
@ -226,79 +250,100 @@ describe('Workspaces', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] },
it('filter workspace', () => {
FleetWorkspaceListPagePo.navTo();
fleetWorkspacesPage.waitForPage();
fleetWorkspacesListPage.waitForPage();
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().checkVisible();
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().checkLoadingIndicatorNotVisible();
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().checkRowCount(false, 10);
fleetWorkspacesListPage.list().resourceTable().sortableTable()
.checkVisible();
fleetWorkspacesListPage.list().resourceTable().sortableTable()
.checkLoadingIndicatorNotVisible();
fleetWorkspacesListPage.list().resourceTable().sortableTable()
.checkRowCount(false, 10);
// filter by name
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().filter(workspaceNameList[0]);
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().checkRowCount(false, 1);
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().rowElementWithName(workspaceNameList[0])
fleetWorkspacesListPage.list().resourceTable().sortableTable()
.filter(workspaceNameList[0]);
fleetWorkspacesListPage.list().resourceTable().sortableTable()
.checkRowCount(false, 1);
fleetWorkspacesListPage.list().resourceTable().sortableTable()
.rowElementWithName(workspaceNameList[0])
.scrollIntoView()
.should('be.visible');
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().resetFilter();
fleetWorkspacesListPage.list().resourceTable().sortableTable()
.resetFilter();
});
it('sorting changes the order of paginated workspace data', () => {
FleetWorkspaceListPagePo.navTo();
fleetWorkspacesPage.waitForPage();
fleetWorkspacesListPage.waitForPage();
// 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');
// workspace name should be visible on first page (sorted in ASC order)
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().tableHeaderRow()
fleetWorkspacesListPage.list().resourceTable().sortableTable()
.tableHeaderRow()
.self()
.scrollIntoView();
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().rowElementWithName(uniqueWorkspaceName)
fleetWorkspacesListPage.list().resourceTable().sortableTable()
.rowElementWithName(uniqueWorkspaceName)
.scrollIntoView()
.should('be.visible');
// navigate to last page
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().pagination()
fleetWorkspacesListPage.list().resourceTable().sortableTable()
.pagination()
.endButton()
.scrollIntoView()
.click();
// 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');
// sort by name in DESC order
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().sort(2)
fleetWorkspacesListPage.list().resourceTable().sortableTable()
.sort(2)
.click();
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().tableHeaderRow()
fleetWorkspacesListPage.list().resourceTable().sortableTable()
.tableHeaderRow()
.checkSortOrder(2, 'up');
// 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');
// navigate to last page
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().pagination()
fleetWorkspacesListPage.list().resourceTable().sortableTable()
.pagination()
.endButton()
.scrollIntoView()
.click();
// 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()
.should('be.visible');
});
it('pagination is hidden', () => {
generateFleetWorkspacesDataSmall();
fleetWorkspacesPage.goTo();
fleetWorkspacesPage.waitForPage();
fleetWorkspacesListPage.goTo();
fleetWorkspacesListPage.waitForPage();
cy.wait('@fleetworkspacesDataSmall');
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().checkVisible();
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().checkLoadingIndicatorNotVisible();
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().checkRowCount(false, 2);
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().pagination()
fleetWorkspacesListPage.list().resourceTable().sortableTable()
.checkVisible();
fleetWorkspacesListPage.list().resourceTable().sortableTable()
.checkLoadingIndicatorNotVisible();
fleetWorkspacesListPage.list().resourceTable().sortableTable()
.checkRowCount(false, 2);
fleetWorkspacesListPage.list().resourceTable().sortableTable()
.pagination()
.checkNotExists();
});
@ -311,99 +356,106 @@ describe('Workspaces', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] },
describe('CRUD', { tags: ['@fleet', '@adminUser'] }, () => {
it('can create a fleet workspace', () => {
const fleetWorkspaceCreateEditPage = new FleetWorkspaceCreateEditPo();
cy.intercept('POST', '/v3/fleetworkspaces').as('createWorkspace');
fleetWorkspacesPage.goTo();
fleetWorkspacesPage.waitForPage();
fleetWorkspacesPage.sharedComponents().baseResourceList().masthead().title()
fleetWorkspacesListPage.goTo();
fleetWorkspacesListPage.waitForPage();
fleetWorkspacesListPage.baseResourceList().masthead().title()
.should('contain', 'Workspaces');
fleetWorkspacesPage.sharedComponents().list().resourceTable().sortableTable()
fleetWorkspacesListPage.list().resourceTable().sortableTable()
.noRowsShouldNotExist();
fleetWorkspacesPage.sharedComponents().baseResourceList().masthead().create();
fleetWorkspacesPage.createWorkspaceForm().waitForPage(null, 'allowedtargetnamespaces');
fleetWorkspacesPage.createWorkspaceForm().mastheadTitle().then((title) => {
fleetWorkspacesListPage.baseResourceList().masthead().create();
fleetWorkspaceCreateEditPage.waitForPage(null, 'allowedtargetnamespaces');
fleetWorkspaceCreateEditPage.mastheadTitle().then((title) => {
expect(title.replace(/\s+/g, ' ')).to.contain('Workspace: Create');
});
fleetWorkspacesPage.createWorkspaceForm().sharedComponents().resourceDetail().createEditView()
fleetWorkspaceCreateEditPage.resourceDetail().createEditView()
.nameNsDescription()
.name()
.set(customWorkspace);
fleetWorkspacesPage.createWorkspaceForm().sharedComponents().resourceDetail().createEditView()
fleetWorkspaceCreateEditPage.resourceDetail().createEditView()
.nameNsDescription()
.description()
.set(`${ customWorkspace }-desc`);
fleetWorkspacesPage.createWorkspaceForm().sharedComponents().resourceDetail().tabs()
fleetWorkspaceCreateEditPage.resourceDetail().tabs()
.allTabs()
.should('have.length.at.least', 2);
const tabs = ['Allowed Target Namespaces', 'Labels & Annotations'];
fleetWorkspacesPage.createWorkspaceForm().sharedComponents().resourceDetail().tabs()
fleetWorkspaceCreateEditPage.resourceDetail().tabs()
.tabNames()
.each((el, i) => {
expect(el).to.eq(tabs[i]);
});
fleetWorkspacesPage.createWorkspaceForm().sharedComponents().resourceDetail().tabs()
fleetWorkspaceCreateEditPage.resourceDetail().tabs()
.assertTabIsActive('[data-testid="allowedtargetnamespaces"]');
fleetWorkspacesPage.createWorkspaceForm().allowTargetNsTabList().setValueAtIndex('test', 0);
fleetWorkspacesPage.createWorkspaceForm().sharedComponents().resourceDetail().tabs()
fleetWorkspaceCreateEditPage.allowTargetNsTabList().setValueAtIndex('test', 0);
fleetWorkspaceCreateEditPage.resourceDetail().tabs()
.clickTabWithSelector('[data-testid="btn-labels"]');
fleetWorkspacesPage.createWorkspaceForm().waitForPage(null, 'labels');
fleetWorkspacesPage.createWorkspaceForm().lablesAnnotationsKeyValue().setKeyValueAtIndex('Add Label', 'label-key1', 'label-value1', 0, 'div.row:nth-of-type(2)');
fleetWorkspaceCreateEditPage.waitForPage(null, 'labels');
fleetWorkspaceCreateEditPage.lablesAnnotationsKeyValue().setKeyValueAtIndex('Add Label', 'label-key1', 'label-value1', 0, 'div.row:nth-of-type(2)');
// Adding Annotations doesn't work via test automation
// 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)');
fleetWorkspacesPage.createWorkspaceForm().sharedComponents().resourceDetail().createEditView()
// fleetWorkspaceCreateEditPage.lablesAnnotationsKeyValue().setKeyValueAtIndex('Add Annotation', 'ann-key1', 'ann-value1', 0, 'div.row:nth-of-type(3)');
fleetWorkspaceCreateEditPage.resourceDetail().createEditView()
.create();
cy.wait('@createWorkspace').then(({ response }) => {
expect(response?.statusCode).to.eq(201);
});
fleetWorkspacesPage.waitForPage();
fleetWorkspacesPage.sharedComponents().list().resourceTable().sortableTable()
fleetWorkspacesListPage.waitForPage();
fleetWorkspacesListPage.list().resourceTable().sortableTable()
.rowWithName(customWorkspace)
.checkVisible();
});
it('user sees custom workspace as an option in workspace selector', () => {
fleetWorkspacesPage.goTo();
fleetWorkspacesPage.waitForPage();
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().noRowsShouldNotExist();
fleetWorkspacesListPage.goTo();
fleetWorkspacesListPage.waitForPage();
fleetWorkspacesListPage.list().resourceTable().sortableTable()
.noRowsShouldNotExist();
headerPo.checkCurrentWorkspace(customWorkspace);
});
it('can Edit Config', () => {
fleetWorkspacesPage.goTo();
fleetWorkspacesPage.waitForPage();
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().noRowsShouldNotExist();
fleetWorkspacesPage.sharedComponents().list().actionMenu(customWorkspace).getMenuItem('Edit Config')
const fleetWorkspaceCreateEditPage = new FleetWorkspaceCreateEditPo(customWorkspace);
fleetWorkspacesListPage.goTo();
fleetWorkspacesListPage.waitForPage();
fleetWorkspacesListPage.list().resourceTable().sortableTable()
.noRowsShouldNotExist();
fleetWorkspacesListPage.list().actionMenu(customWorkspace).getMenuItem('Edit Config')
.click();
fleetWorkspacesPage.createWorkspaceForm(customWorkspace).waitForPage('mode=edit', 'allowedtargetnamespaces');
fleetWorkspacesPage.createWorkspaceForm().mastheadTitle().then((title) => {
fleetWorkspaceCreateEditPage.waitForPage('mode=edit', 'allowedtargetnamespaces');
fleetWorkspaceCreateEditPage.mastheadTitle().then((title) => {
expect(title.replace(/\s+/g, ' ')).to.contain(`Workspace: ${ customWorkspace }`);
});
fleetWorkspacesPage.createWorkspaceForm().sharedComponents().resourceDetail().createEditView()
fleetWorkspaceCreateEditPage.resourceDetail().createEditView()
.nameNsDescription()
.description()
.set(`${ customWorkspace }-desc-edit`);
fleetWorkspacesPage.createWorkspaceForm().sharedComponents().resourceDetail().cruResource()
fleetWorkspaceCreateEditPage.resourceDetail().cruResource()
.saveAndWaitForRequests('PUT', `/v3/fleetWorkspaces/${ customWorkspace }`)
.then(({ response }) => {
expect(response?.statusCode).to.eq(200);
expect(response?.body.id).to.equal(customWorkspace);
expect(response?.body.annotations).to.have.property('field.cattle.io/description', `${ customWorkspace }-desc-edit`);
});
fleetWorkspacesPage.waitForPage();
fleetWorkspacesListPage.waitForPage();
});
it('can Download YAML', () => {
cy.deleteDownloadsFolder();
fleetWorkspacesPage.goTo();
fleetWorkspacesPage.waitForPage();
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().noRowsShouldNotExist();
fleetWorkspacesPage.sharedComponents().list().actionMenu(customWorkspace).getMenuItem('Download YAML')
fleetWorkspacesListPage.goTo();
fleetWorkspacesListPage.waitForPage();
fleetWorkspacesListPage.list().resourceTable().sortableTable()
.noRowsShouldNotExist();
fleetWorkspacesListPage.list().actionMenu(customWorkspace).getMenuItem('Download YAML')
.click();
const downloadedFilename = path.join(downloadsFolder, `${ customWorkspace }.yaml`);
@ -418,12 +470,13 @@ describe('Workspaces', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] },
});
it('can delete workspace', () => {
fleetWorkspacesPage.goTo();
fleetWorkspacesPage.waitForPage();
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().noRowsShouldNotExist();
fleetWorkspacesPage.sharedComponents().list().actionMenu(customWorkspace).getMenuItem('Delete')
fleetWorkspacesListPage.goTo();
fleetWorkspacesListPage.waitForPage();
fleetWorkspacesListPage.list().resourceTable().sortableTable()
.noRowsShouldNotExist();
fleetWorkspacesListPage.list().actionMenu(customWorkspace).getMenuItem('Delete')
.click();
fleetWorkspacesPage.sharedComponents().list().resourceTable().sortableTable()
fleetWorkspacesListPage.list().resourceTable().sortableTable()
.rowNames('.col-link-detail')
.then((rows: any) => {
const promptRemove = new PromptRemove();
@ -433,10 +486,10 @@ describe('Workspaces', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] },
promptRemove.confirmField().set(customWorkspace);
promptRemove.remove();
cy.wait('@deleteWorkspace');
fleetWorkspacesPage.waitForPage();
fleetWorkspacesPage.sharedComponents().list().resourceTable().sortableTable()
fleetWorkspacesListPage.waitForPage();
fleetWorkspacesListPage.list().resourceTable().sortableTable()
.checkRowCount(false, rows.length - 1);
fleetWorkspacesPage.sharedComponents().list().resourceTable().sortableTable()
fleetWorkspacesListPage.list().resourceTable().sortableTable()
.rowNames('.col-link-detail')
.should('not.contain', customWorkspace);
});

View File

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

View File

@ -1,7 +1,4 @@
import { FleetDashboardPagePo } 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 { FleetDashboardListPagePo } from '@/cypress/e2e/po/pages/fleet/fleet-dashboard.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 { 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 * as path from 'path';
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');
describe('Fleet Dashboard', { tags: ['@fleet', '@adminUser', '@jenkins'] }, () => {
const fleetDashboardPage = new FleetDashboardPagePo('_');
const gitRepoCreatePage = new GitRepoCreatePo('_');
const fleetDashboardPage = new FleetDashboardListPagePo('_');
const gitRepoCreatePage = new FleetGitRepoCreateEditPo();
const headerPo = new HeaderPo();
let repoName;
@ -70,7 +67,7 @@ describe('Fleet Dashboard', { tags: ['@fleet', '@adminUser', '@jenkins'] }, () =
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"] 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"] span').should('have.text', '1/1');
@ -84,7 +81,7 @@ describe('Fleet Dashboard', { tags: ['@fleet', '@adminUser', '@jenkins'] }, () =
fleetDashboardPage.goTo();
fleetDashboardPage.waitForPage();
fleetDashboardPage.sharedComponents().goToDetailsPage(repoName);
fleetDashboardPage.collapsibleTable(localWorkspace).goToDetailsPage(repoName);
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/secrets?exclude=metadata.managedFields').as('getSecrets');
const gitRepoEditPage = new GitRepoEditPo(localWorkspace, repoName);
const gitRepoEditPage = new FleetGitRepoCreateEditPo(localWorkspace, repoName);
fleetDashboardPage.goTo();
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 }`);
});
headerPo.selectWorkspace(defaultWorkspace);
gitRepoEditPage.sharedComponents().resourceDetail().createEditView().nameNsDescription()
gitRepoEditPage.resourceDetail().createEditView().nameNsDescription()
.name()
.set(`clone-${ repoName }`);
gitRepoEditPage.sharedComponents().resourceDetail().createEditView().nextPage();
gitRepoEditPage.sharedComponents().resourceDetail().createEditView().nextPage();
gitRepoEditPage.sharedComponents().resourceDetail().createEditView().nextPage();
gitRepoEditPage.resourceDetail().createEditView().nextPage();
gitRepoEditPage.resourceDetail().createEditView().nextPage();
gitRepoEditPage.resourceDetail().createEditView().nextPage();
cy.wait('@getSecrets', MEDIUM_TIMEOUT_OPT).its('response.statusCode').should('eq', 200);
gitRepoEditPage.sharedComponents().resourceDetail().createEditView().create()
gitRepoEditPage.resourceDetail().createEditView().create()
.then(() => {
removeGitRepo = true;
reposToDelete.push(`${ defaultWorkspace }/clone-${ repoName }`);
});
FleetDashboardPagePo.navTo();
FleetDashboardListPagePo.navTo();
fleetDashboardPage.waitForPage();
fleetDashboardPage.collapsibleTable(defaultWorkspace).sortableTable().rowElementWithName(`clone-${ 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', () => {
const gitRepoEditPage = new GitRepoEditPo(localWorkspace, repoName);
const gitRepoEditPage = new FleetGitRepoCreateEditPo(localWorkspace, repoName);
fleetDashboardPage.goTo();
fleetDashboardPage.waitForPage();
@ -209,7 +206,7 @@ describe('Fleet Dashboard', { tags: ['@fleet', '@adminUser', '@jenkins'] }, () =
});
it('can Edit Config', () => {
const gitRepoEditPage = new GitRepoEditPo(localWorkspace, repoName);
const gitRepoEditPage = new FleetGitRepoCreateEditPo(localWorkspace, repoName);
const description = `${ repoName }-desc`;
fleetDashboardPage.goTo();
@ -218,11 +215,11 @@ describe('Fleet Dashboard', { tags: ['@fleet', '@adminUser', '@jenkins'] }, () =
.click();
gitRepoEditPage.waitForPage('mode=edit');
gitRepoEditPage.sharedComponents().resourceDetail().createEditView().nameNsDescription()
gitRepoEditPage.resourceDetail().createEditView().nameNsDescription()
.description()
.set(description);
gitRepoEditPage.sharedComponents().resourceDetail().createEditView().nextPage();
gitRepoEditPage.sharedComponents().resourceDetail().createEditView().save();
gitRepoEditPage.resourceDetail().createEditView().nextPage();
gitRepoEditPage.resourceDetail().createEditView().save();
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 { MenuActions } from '@/cypress/support/types/menu-actions';
import { gitRepoTargetAllClustersRequest } from '@/cypress/e2e/blueprints/fleet/gitrepos';
import { FleetGitRepoListPagePo } 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 { FleetGitRepoListPagePo, FleetGitRepoCreateEditPo } from '@/cypress/e2e/po/pages/fleet/fleet.cattle.io.gitrepo.po';
import { WorkloadsDeploymentsListPagePo } from '@/cypress/e2e/po/pages/explorer/workloads/workloads-deployments.po';
import * as path from 'path';
import * as jsyaml from 'js-yaml';
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 { FeatureFlagsPagePo } from '@/cypress/e2e/po/pages/global-settings/feature-flags.po';
describe('Fleet Clusters', { tags: ['@fleet', '@adminUser'] }, () => {
const fleetClusterListPage = new FleetClusterListPagePo();
const fleetGitRepoListPage = new FleetGitRepoListPagePo();
const fleetGitRepoPage = new FleetGitRepoListPagePo();
const clusterList = new ClusterManagerListPagePo();
const featureFlagsPage = new FeatureFlagsPagePo();
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
fleetGitRepoListPage.navTo();
fleetGitRepoListPage.waitForPage();
fleetGitRepoPage.navTo();
fleetGitRepoPage.waitForPage();
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
FleetClusterListPagePo.navTo();
fleetClusterListPage.waitForPage();
headerPo.selectWorkspace(namespace);
fleetClusterListPage.sharedComponents().resourceTable().sortableTable().checkLoadingIndicatorNotVisible();
fleetClusterListPage.list().resourceTable().sortableTable()
.checkLoadingIndicatorNotVisible();
// check name
fleetClusterListPage.sharedComponents().resourceTableDetails(clusterName, 2).should('be.visible');
fleetClusterListPage.resourceTableDetails(clusterName, 2).should('be.visible');
// check cluster state in fleet
fleetClusterListPage.sharedComponents().resourceTableDetails(clusterName, 1).contains('Not Ready', MEDIUM_TIMEOUT_OPT);
fleetClusterListPage.sharedComponents().resourceTableDetails(clusterName, 1).contains('Active', LONG_TIMEOUT_OPT);
fleetClusterListPage.resourceTableDetails(clusterName, 1).contains('Not Ready', MEDIUM_TIMEOUT_OPT);
fleetClusterListPage.resourceTableDetails(clusterName, 1).contains('Active', LONG_TIMEOUT_OPT);
// check bundles ready
fleetClusterListPage.sharedComponents().resourceTableDetails(clusterName, 3).should('have.text', '4');
fleetClusterListPage.resourceTableDetails(clusterName, 3).should('have.text', '4');
// 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
fleetClusterListPage.sharedComponents().resourceTableDetails(clusterName, 5).contains( ' 15 ', MEDIUM_TIMEOUT_OPT);
fleetClusterListPage.resourceTableDetails(clusterName, 5).contains( ' 15 ', MEDIUM_TIMEOUT_OPT);
// check cluster labels
fleetClusterListPage.sharedComponents().resourceTable().sortableTable().subRows()
fleetClusterListPage.list().resourceTable().sortableTable()
.subRows()
.should('contain.text', 'foo=bar');
const fleetClusterDetailsPage = new FleetClusterDetailsPo(namespace, clusterName);
// go to cluster details in fleet
fleetClusterListPage.sharedComponents().resourceTableDetails(clusterName, 2).find('a').click();
fleetClusterListPage.goToDetailsPage(clusterName);
fleetClusterDetailsPage.waitForPage(null, 'repos');
fleetClusterDetailsPage.clusterTabs().clickTabWithSelector('[data-testid="btn-repos"]');
// check state
fleetClusterDetailsPage.gitReposList().details(gitRepo, 1).contains('Ready');
fleetClusterDetailsPage.gitReposList().resourceTableDetails(gitRepo, 1).contains('Ready');
// check name
fleetClusterDetailsPage.gitReposList().details(gitRepo, 2).should('be.visible');
fleetClusterDetailsPage.gitReposList().resourceTableDetails(gitRepo, 2).should('be.visible');
// 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
fleetClusterDetailsPage.gitReposList().details(gitRepo, 4).contains('Advanced');
fleetClusterDetailsPage.gitReposList().resourceTableDetails(gitRepo, 4).contains('Advanced');
// 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', () => {
@ -155,7 +155,7 @@ describe('Fleet Clusters', { tags: ['@fleet', '@adminUser'] }, () => {
FleetClusterListPagePo.navTo();
fleetClusterListPage.waitForPage();
headerPo.selectWorkspace(namespace);
fleetClusterListPage.sharedComponents().resourceTableDetails(clusterName, 2).find('a').click();
fleetClusterListPage.goToDetailsPage(clusterName);
fleetClusterDetailsPage.waitForPage(null, 'repos');
fleetClusterDetailsPage.clusterTabs().allTabs().should('have.length', 4, { timeout: 10000 });
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');
// pause
fleetClusterListPage.sharedComponents().list().actionMenu(clusterName).getMenuItem('Pause')
fleetClusterListPage.list().actionMenu(clusterName).getMenuItem('Pause')
.click();
cy.wait('@pause').then(({ response }) => {
expect(response?.statusCode).to.eq(200);
@ -194,7 +194,7 @@ describe('Fleet Clusters', { tags: ['@fleet', '@adminUser'] }, () => {
});
// 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', () => {
@ -206,7 +206,7 @@ describe('Fleet Clusters', { tags: ['@fleet', '@adminUser'] }, () => {
cy.intercept('PUT', `v1/fleet.cattle.io.clusters/${ namespace }/${ clusterName }`).as('unpause');
// unpause
fleetClusterListPage.sharedComponents().list().actionMenu(clusterName).getMenuItem('Unpause')
fleetClusterListPage.list().actionMenu(clusterName).getMenuItem('Unpause')
.click();
cy.wait('@unpause').then(({ response }) => {
expect(response?.statusCode).to.eq(200);
@ -216,7 +216,7 @@ describe('Fleet Clusters', { tags: ['@fleet', '@adminUser'] }, () => {
});
// 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', () => {
@ -224,16 +224,16 @@ describe('Fleet Clusters', { tags: ['@fleet', '@adminUser'] }, () => {
FleetClusterListPagePo.navTo();
fleetClusterListPage.waitForPage();
headerPo.selectWorkspace(namespace);
fleetClusterListPage.sharedComponents().list().actionMenu(clusterName).getMenuItem('Edit Config')
fleetClusterListPage.list().actionMenu(clusterName).getMenuItem('Edit Config')
.click();
const editFleetCluster = fleetClusterListPage.editFleetCluster(undefined, clusterName);
editFleetCluster.waitForPage('mode=edit');
editFleetCluster.sharedComponents().resourceDetail().createEditView().nameNsDescription()
editFleetCluster.resourceDetail().createEditView().nameNsDescription()
.description()
.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 }) => {
expect(response?.statusCode).to.eq(200);
expect(response?.body.metadata).to.have.property('name', clusterName);
@ -248,7 +248,7 @@ describe('Fleet Clusters', { tags: ['@fleet', '@adminUser'] }, () => {
FleetClusterListPagePo.navTo();
fleetClusterListPage.waitForPage();
headerPo.selectWorkspace(namespace);
fleetClusterListPage.sharedComponents().list().actionMenu(clusterName).getMenuItem('Download YAML')
fleetClusterListPage.list().actionMenu(clusterName).getMenuItem('Download YAML')
.click();
const downloadedFilename = path.join(downloadsFolder, `${ clusterName }.yaml`);
@ -286,32 +286,34 @@ describe('Fleet Clusters', { tags: ['@fleet', '@adminUser'] }, () => {
headerPo.selectWorkspace(namespace);
cy.intercept('PUT', '/v1/userpreferences/*').as('changeWorkspace');
fleetClusterListPage.sharedComponents().list().actionMenu(clusterName).getMenuItem('Change workspace')
fleetClusterListPage.list().actionMenu(clusterName).getMenuItem('Change workspace')
.click();
fleetClusterListPage.changeWorkspaceForm().workspaceSelect().toggle();
fleetClusterListPage.changeWorkspaceForm().workspaceSelect().clickOptionWithLabel(customWorkspace);
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();
fleetClusterListPage.waitForPage();
headerPo.selectWorkspace(customWorkspace);
cy.wait('@changeWorkspace');
fleetClusterListPage.sharedComponents().resourceTableDetails(clusterName, 2).isVisible();
fleetClusterListPage.resourceTableDetails(clusterName, 2).isVisible();
// restore
fleetClusterListPage.sharedComponents().list().actionMenu(clusterName).getMenuItem('Change workspace')
fleetClusterListPage.list().actionMenu(clusterName).getMenuItem('Change workspace')
.click();
fleetClusterListPage.changeWorkspaceForm().workspaceSelect().toggle();
fleetClusterListPage.changeWorkspaceForm().workspaceSelect().clickOptionWithLabel(namespace);
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();
fleetClusterListPage.waitForPage();
headerPo.selectWorkspace(namespace);
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)', () => {
@ -338,8 +340,10 @@ describe('Fleet Clusters', { tags: ['@fleet', '@adminUser'] }, () => {
FleetClusterListPagePo.navTo();
fleetClusterListPage.waitForPage();
headerPo.selectWorkspace(namespace);
fleetClusterListPage.sharedComponents().resourceTable().sortableTable().checkLoadingIndicatorNotVisible();
fleetClusterListPage.sharedComponents().resourceTable().sortableTable().checkRowCount(true, 1, MEDIUM_TIMEOUT_OPT);
fleetClusterListPage.list().resourceTable().sortableTable()
.checkLoadingIndicatorNotVisible();
fleetClusterListPage.list().resourceTable().sortableTable()
.checkRowCount(true, 1, MEDIUM_TIMEOUT_OPT);
});
after('clean up', () => {
@ -384,18 +388,20 @@ describe('Fleet Clusters', { tags: ['@fleet', '@adminUser'] }, () => {
});
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', () => {
// testing https://github.com/rancher/dashboard/issues/11198
const fleetClusterDetailsPage = new FleetClusterDetailsPo(workspace, 'local');
const gitRepoCreatePage = new GitRepoCreatePo('_');
const gitRepoCreatePage = new FleetGitRepoCreateEditPo();
fleetClusterListPage.sharedComponents().resourceTable().sortableTable().checkLoadingIndicatorNotVisible();
fleetClusterListPage.sharedComponents().resourceTableDetails('local', 2).find('a').click();
fleetClusterListPage.list().resourceTable().sortableTable()
.checkLoadingIndicatorNotVisible();
fleetClusterListPage.goToDetailsPage('local');
fleetClusterDetailsPage.waitForPage(null, 'repos');
fleetClusterDetailsPage.gitReposTab().addRepostoryButton().click();
fleetClusterDetailsPage.addRepostoryButton().click();
gitRepoCreatePage.waitForPage();
gitRepoCreatePage.mastheadTitle().then((title) => {
expect(title.replace(/\s+/g, ' ')).to.contain('Git Repo: Create');
@ -406,7 +412,8 @@ describe('Fleet Clusters', { tags: ['@fleet', '@adminUser'] }, () => {
fleetClusterListPage.goTo();
headerPo.selectWorkspace(workspace);
const constActionMenu = fleetClusterListPage.sharedComponents().resourceTable().sortableTable().rowActionMenuOpen('local');
const constActionMenu = fleetClusterListPage.list().resourceTable().sortableTable()
.rowActionMenuOpen('local');
const allowedActions: MenuActions[] = [
MenuActions.Pause,
@ -437,10 +444,10 @@ describe('Fleet Clusters', { tags: ['@fleet', '@adminUser'] }, () => {
});
// go to fleet gitrepo
fleetGitRepoListPage.navTo();
fleetGitRepoListPage.waitForPage();
fleetGitRepoPage.navTo();
fleetGitRepoPage.waitForPage();
headerPo.selectWorkspace(workspace);
fleetGitRepoListPage.sharedComponents().list().rowWithName(gitRepo).checkVisible();
fleetGitRepoPage.list().rowWithName(gitRepo).checkVisible();
// go to fleet cluster list
FleetClusterListPagePo.navTo();
@ -449,7 +456,7 @@ describe('Fleet Clusters', { tags: ['@fleet', '@adminUser'] }, () => {
// check table headers
const expectedHeaders = ['State', 'Name', 'Bundles Ready', 'Repos Ready', 'Resources', 'Last Seen', 'Age'];
fleetClusterListPage.sharedComponents().list().resourceTable().sortableTable()
fleetClusterListPage.list().resourceTable().sortableTable()
.tableHeaderRow()
.within('.table-header-container .content')
.each((el, i) => {
@ -457,7 +464,7 @@ describe('Fleet Clusters', { tags: ['@fleet', '@adminUser'] }, () => {
});
// 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);
@ -466,7 +473,7 @@ describe('Fleet Clusters', { tags: ['@fleet', '@adminUser'] }, () => {
// check table headers
const expectedHeadersDetailsView = ['Cluster State', 'Name', 'Repo', 'Target', 'Cluster Resources', 'Age'];
fleetClusterDetailsPage.gitReposTab().list().resourceTable().sortableTable()
fleetClusterDetailsPage.gitReposList().sortableTable()
.tableHeaderRow()
.within('.table-header-container .content')
.each((el, i) => {

View File

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

View File

@ -1,6 +1,6 @@
import { PerformancePagePo } from '@/cypress/e2e/po/pages/global-settings/performance.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 performanceSettingsOriginal = [];
@ -176,7 +176,7 @@ describe('Performance', { testIsolation: 'off', tags: ['@globalSettings', '@admi
performancePage.namespaceFilteringCheckbox().set();
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.applyAndWait('forceNsFilterV2-true').then(({ request, response }) => {
expect(response?.statusCode).to.eq(200);

View File

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

View File

@ -1,7 +1,7 @@
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 * 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'] }, () => {
const clusterList = new ClusterManagerListPagePo();
@ -48,7 +48,7 @@ describe('Cluster List', { tags: ['@manager', '@adminUser'] }, () => {
createRKE2ClusterPage.waitForPage();
createRKE2ClusterPage.resourceDetail().createEditView().editClusterAsYaml();
promptModal().checkVisible();
promptModal().submit('Save and Continue');
promptModal().clickActionButton('Save and Continue');
createRKE2ClusterPage.waitForPage('type=custom&rkeType=rke2', 'basic');
// provision cluster into a custom namespace
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 KontainerDriversPagePo from '@/cypress/e2e/po/pages/cluster-manager/kontainer-drivers.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
const runTimestamp = +new Date();
@ -596,7 +597,7 @@ describe('Cluster Manager', { testIsolation: 'off', tags: ['@manager', '@adminUs
describe('Generic', () => {
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');
clusterList.goTo();
@ -619,6 +620,9 @@ describe('Cluster Manager', { testIsolation: 'off', tags: ['@manager', '@adminUs
importClusterPage.nameNsDescription().name().checkVisible();
importClusterPage.nameNsDescription().name().set(importGenericName);
// Issue #13614: Imported Cluster Version Mgmt: Conditionally show warning message
importClusterPage.versionManagementBanner().should('exist').and('be.visible');
importClusterPage.create();
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', () => {
const editImportedClusterPage = new ClusterManagerEditImportedPagePo(undefined, importedClusterName);
const editImportedClusterPage = new ClusterManagerEditImportedPagePo(undefined, 'fleet-default', importedClusterName);
cy.intercept('GET', '/v1-rke2-release/releases').as('getRke2Releases');
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
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.ace().enable();
editImportedClusterPage.ace().enterFdqn(fqdn);
@ -798,14 +809,48 @@ describe('Cluster Manager', { testIsolation: 'off', tags: ['@manager', '@adminUs
});
});
it(`can navigate to local cluster's explore product`, () => {
const clusterName = 'local';
const clusterDashboard = new ClusterDashboardPagePo(clusterName);
describe('Local', { tags: ['@jenkins', '@localCluster'] }, () => {
it(`can open edit for local cluster`, () => {
const editLocalClusterPage = new ClusterManagerEditImportedPagePo(undefined, 'fleet-local', 'local');
clusterList.goTo();
clusterList.list().explore(clusterName).click();
cy.intercept('GET', '/v1-rke2-release/releases').as('getRke2Releases');
clusterList.goTo();
clusterList.list().actionMenu('local').getMenuItem('Edit Config').click();
editLocalClusterPage.waitForPage('mode=edit');
clusterDashboard.waitForPage(undefined, 'cluster-events');
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`, () => {
const clusterName = 'local';
const clusterDashboard = new ClusterDashboardPagePo(clusterName);
clusterList.goTo();
clusterList.list().explore(clusterName).click();
clusterDashboard.waitForPage(undefined, 'cluster-events');
});
});
it('can download YAML via bulk actions', () => {

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 TabbedPo from '@/cypress/e2e/po/components/tabbed.po';
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
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.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) => {
expect(req.response?.statusCode).to.equal(201);
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 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 { USERS_BASE_URL } from '@/cypress/support/utils/api-endpoints';
/******
* 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.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) => {
expect(req.response?.statusCode).to.equal(201);
cloudcredentialId = req.response?.body.id.replace(':', '%3A');

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