diff --git a/cypress/e2e/po/components/action-menu-shell.po.ts b/cypress/e2e/po/components/action-menu-shell.po.ts new file mode 100644 index 0000000000..55a60a978a --- /dev/null +++ b/cypress/e2e/po/components/action-menu-shell.po.ts @@ -0,0 +1,15 @@ +import ComponentPo from '@/cypress/e2e/po/components/component.po'; + +export default class ActionMenuPo extends ComponentPo { + constructor(arg:any) { + super(arg || cy.get('[dropdown-menu-collection]')); + } + + clickMenuItem(index: number) { + return this.self().find('[dropdown-menu-item]').eq(index).click(); + } + + getMenuItem(name: string) { + return this.self().get('[dropdown-menu-item]').contains(name); + } +} diff --git a/cypress/e2e/po/components/list-row.po.ts b/cypress/e2e/po/components/list-row.po.ts index 2ff080300f..2e8cc4e3b2 100644 --- a/cypress/e2e/po/components/list-row.po.ts +++ b/cypress/e2e/po/components/list-row.po.ts @@ -11,7 +11,7 @@ export default class ListRowPo extends ComponentPo { * the action button could be in a different column */ actionBtn() { - return this.self().find('.btn.actions'); + return this.self().find('[data-testid*="action-button"]'); } get(selector: string, options?: any) { diff --git a/cypress/e2e/po/components/shell.po.ts b/cypress/e2e/po/components/shell.po.ts index fbac1f562e..c111d3ce58 100644 --- a/cypress/e2e/po/components/shell.po.ts +++ b/cypress/e2e/po/components/shell.po.ts @@ -7,9 +7,9 @@ export default class Shell extends ComponentPo { openTerminal() { // get and click on the first row's action menu button - cy.get(`button[data-testid="sortable-table-0-action-button"]`).first().click(); + cy.get(`[data-testid="sortable-table-0-action-button"`).first().click(); // get and click on the action menu's first option (execute shell) - cy.get(`li[data-testid="action-menu-0-item"]`).click(); + cy.get(`[dropdown-menu-item]`).contains('Execute Shell').click(); this.self().get('.window.show-grid .text-success').should('contain', 'Connected'); return this; diff --git a/cypress/e2e/po/components/sortable-table.po.ts b/cypress/e2e/po/components/sortable-table.po.ts index 5e76ba836b..0c2063ee23 100644 --- a/cypress/e2e/po/components/sortable-table.po.ts +++ b/cypress/e2e/po/components/sortable-table.po.ts @@ -1,5 +1,5 @@ import ComponentPo, { GetOptions } from '@/cypress/e2e/po/components/component.po'; -import ActionMenuPo from '@/cypress/e2e/po/components/action-menu.po'; +import ActionMenuPo from '@/cypress/e2e/po/components/action-menu-shell.po'; import CheckboxInputPo from '@/cypress/e2e/po/components/checkbox-input.po'; import ListRowPo from '@/cypress/e2e/po/components/list-row.po'; import PromptRemove from '@/cypress/e2e/po/prompts/promptRemove.po'; diff --git a/cypress/e2e/po/lists/chart-repositories.po.ts b/cypress/e2e/po/lists/chart-repositories.po.ts index 2ebf4a605a..8842dc88f1 100644 --- a/cypress/e2e/po/lists/chart-repositories.po.ts +++ b/cypress/e2e/po/lists/chart-repositories.po.ts @@ -9,7 +9,7 @@ export default class ChartRepositoriesListPo extends BaseResourceList { } closeActionMenu() { - cy.get('body').click(0, 0); // Click outside of the action menu + cy.get('body').type('{esc}'); } openBulkActionDropdown() { @@ -25,8 +25,11 @@ export default class ChartRepositoriesListPo extends BaseResourceList { } refreshRepo(repoName: string) { - return this.resourceTable().sortableTable().rowActionMenuOpen(repoName).getMenuItem('Refresh') - .click(); + return this.resourceTable() + .sortableTable() + .rowActionMenuOpen(repoName) + .getMenuItem('Refresh') + .click({ force: true }); // We shouldn't require force, but other methods don't work } state(repoName: string) { diff --git a/cypress/e2e/po/pages/global-settings/settings.po.ts b/cypress/e2e/po/pages/global-settings/settings.po.ts index 81552c9873..1797dc8f3a 100644 --- a/cypress/e2e/po/pages/global-settings/settings.po.ts +++ b/cypress/e2e/po/pages/global-settings/settings.po.ts @@ -33,7 +33,7 @@ export class SettingsPagePo extends RootClusterPage { * @returns */ actionButtonByLabel(label: string) { - return this.advancedSettingRow(label).find('.action > button'); + return this.advancedSettingRow(label).find('[data-testid*="action-button"]'); } /** diff --git a/cypress/e2e/po/side-bars/page-actions.po.ts b/cypress/e2e/po/side-bars/page-actions.po.ts index c35c287b16..60d618a857 100644 --- a/cypress/e2e/po/side-bars/page-actions.po.ts +++ b/cypress/e2e/po/side-bars/page-actions.po.ts @@ -10,7 +10,7 @@ export default class PageActionsPo extends ComponentPo { * @returns {Cypress.Chainable} */ static open(): Cypress.Chainable { - return cy.getId('page-actions-menu').should('be.visible').click(); + return cy.getId('page-actions-menu-action-button').should('be.visible').click(); } /** diff --git a/cypress/e2e/tests/pages/manager/repositories.spec.ts b/cypress/e2e/tests/pages/manager/repositories.spec.ts index a7cf99fd78..278a63827b 100644 --- a/cypress/e2e/tests/pages/manager/repositories.spec.ts +++ b/cypress/e2e/tests/pages/manager/repositories.spec.ts @@ -88,7 +88,7 @@ describe('Cluster Management Helm Repositories', { testIsolation: 'off', tags: [ ChartRepositoriesPagePo.navTo(); repositoriesPage.waitForPage(); cy.intercept('PUT', `/v1/catalog.cattle.io.clusterrepos/${ this.repoName }`).as('refreshRepo'); - repositoriesPage.list().actionMenu(this.repoName).getMenuItem('Refresh').click(); + repositoriesPage.list().actionMenu(this.repoName).getMenuItem('Refresh').click({ force: true }); cy.wait('@refreshRepo').its('response.statusCode').should('eq', 200); // check list details @@ -278,7 +278,10 @@ describe('Cluster Management Helm Repositories', { testIsolation: 'off', tags: [ repositoriesPage.list().actionMenu(this.repoName).getMenuItem('Refresh').should('be.visible'); // close action menu repositoriesPage.list().closeActionMenu(); + // disable repo + // eslint-disable-next-line cypress/no-unnecessary-waiting + cy.wait(1500); repositoriesPage.list().actionMenu(this.repoName).getMenuItem('Disable').click(); repositoriesPage.list().details(this.repoName, 1).contains('Disabled', { timeout: 10000 }).scrollIntoView() .should('be.visible'); @@ -287,7 +290,10 @@ describe('Cluster Management Helm Repositories', { testIsolation: 'off', tags: [ repositoriesPage.list().actionMenu(this.repoName).getMenuItem('Refresh').should('not.exist'); // close action menu repositoriesPage.list().closeActionMenu(); + // enable repo + // eslint-disable-next-line cypress/no-unnecessary-waiting + cy.wait(1500); repositoriesPage.list().actionMenu(this.repoName).getMenuItem('Enable').click(); repositoriesPage.list().details(this.repoName, 1).contains('Active', LONG_TIMEOUT_OPT).scrollIntoView() .should('be.visible'); diff --git a/jest.config.js b/jest.config.js index 7d7edb46f2..b5e16207a1 100644 --- a/jest.config.js +++ b/jest.config.js @@ -37,6 +37,7 @@ module.exports = { transform: { '^.+\\.js$': '/node_modules/babel-jest', // process js with `babel-jest` '.*\\.(vue)$': '/node_modules/@vue/vue3-jest', // process `*.vue` files with `vue-jest` + '^.+\\.vue$': './vue3JestRegisterTs.js', // point to a different transformer than vue-jest and call registerTs before exporting vue-jest '^.+\\.tsx?$': 'ts-jest', // process `*.ts` files with `ts-jest` '^.+\\.svg$': '/svgTransform.js' // to mock `*.svg` files }, diff --git a/pkg/rancher-components/src/components/RcButton/RcButton.vue b/pkg/rancher-components/src/components/RcButton/RcButton.vue index 2301c01687..8ed37ed5b4 100644 --- a/pkg/rancher-components/src/components/RcButton/RcButton.vue +++ b/pkg/rancher-components/src/components/RcButton/RcButton.vue @@ -65,25 +65,30 @@ defineExpose({ focus });