From 41cc819ebda3be4a1e37d790a1084884993b7c66 Mon Sep 17 00:00:00 2001 From: Jeffrey Phillips Date: Thu, 21 Nov 2024 08:39:15 -0500 Subject: [PATCH] e2e test fixes --- .../cypress/cypress/pages/clusterStorage.ts | 8 ++++ .../cypress/pages/components/Pagination.ts | 2 +- .../cypress/cypress/pages/components/table.ts | 4 ++ .../cypress/cypress/pages/connectionTypes.ts | 2 +- .../cypress/cypress/pages/modelServing.ts | 2 +- .../cypress/pages/notebookImageSettings.ts | 2 +- .../cypress/pages/pipelines/compareRuns.ts | 2 +- .../pages/pipelines/pipelineRunTable.ts | 2 +- .../cypress/pages/pipelines/pipelinesTable.ts | 2 +- .../cypress/cypress/pages/projects.ts | 6 +-- .../cypress/cypress/pages/userManagement.ts | 2 +- .../cypress/cypress/pages/workbench.ts | 6 +-- .../cypress/support/commands/application.ts | 29 ++++++++++++++ .../acceleratorProfiles.cy.ts | 5 ++- .../manageAcceleratorProfiles.cy.ts | 13 ++++--- .../mocked/applications/administration.cy.ts | 2 +- .../connectionTypes/connectionTypes.cy.ts | 7 +++- .../createConnectionType.cy.ts | 4 +- .../customServingRuntimes.cy.ts | 18 +++++++-- .../modelRegistry/modelVersionArchive.cy.ts | 12 ++++-- .../modelRegistry/modelVersionDeploy.cy.ts | 12 +++--- .../modelRegistry/modelVersionDetails.cy.ts | 6 +-- .../registeredModelArchive.cy.ts | 6 +-- .../modelRegistryPermissions.cy.ts | 30 ++++++++++++--- .../modelRegistrySettings.cy.ts | 6 +-- .../modelServing/modelServingGlobal.cy.ts | 7 +++- .../mocked/modelServing/modelServingNim.cy.ts | 10 ++++- .../modelServing/servingRuntimeList.cy.ts | 28 ++++++++++---- .../notebookImageSettings.cy.ts | 24 ++++++++++-- .../tests/mocked/pipelines/experiments.cy.ts | 8 ++-- .../mocked/pipelines/pipelineCreateRuns.cy.ts | 9 +++-- .../mocked/pipelines/pipelineDeleteRuns.cy.ts | 5 ++- .../tests/mocked/pipelines/pipelineRuns.cy.ts | 2 +- .../tests/mocked/pipelines/pipelines.cy.ts | 38 +++++++++++-------- .../mocked/pipelines/pipelinesList.cy.ts | 11 ++++-- .../mocked/projects/clusterStorage.cy.ts | 22 +++++------ .../mocked/projects/dataConnection.cy.ts | 8 +++- .../tests/mocked/projects/permissions.cy.ts | 20 ++++++++-- .../tests/mocked/projects/projectList.cy.ts | 13 ++++--- .../tests/mocked/projects/workbench.cy.ts | 4 +- .../storageClasses/storageClasses.cy.ts | 9 +++-- frontend/src/app/AppLauncher.tsx | 2 +- frontend/src/components/EmptyDetailsView.tsx | 1 + frontend/src/components/FilterToolbar.tsx | 1 + frontend/src/components/MultiSelection.tsx | 4 ++ frontend/src/components/SimpleMenuActions.tsx | 4 +- .../searchSelector/SearchSelector.tsx | 3 +- frontend/src/components/table/TableBase.tsx | 1 + .../dashboard/DashboardSearchField.tsx | 1 + .../metrics/kserve/KserveMetricsContext.tsx | 8 +++- .../contentSections/TriggerTypeField.tsx | 1 + .../import/ImportPipelineSplitButton.tsx | 1 + .../pipelineRun/runLogs/LogsTab.tsx | 1 + .../tables/experiment/ExperimentTableRow.tsx | 2 +- .../tables/pipeline/PipelinesTableRow.tsx | 1 + .../PipelineRecurringRunTableRow.tsx | 1 + .../pipelineRun/PipelineRunTableRow.tsx | 1 + .../PipelineRunTableToolbarBase.tsx | 2 +- .../PipelineVersionTableRow.tsx | 1 + .../RoleBindingPermissionsTableRow.tsx | 1 + .../pages/BYONImages/BYONImagesTableRow.tsx | 1 + .../list/AcceleratorProfilesTableRow.tsx | 1 + .../manage/tolerations/TolerationRow.tsx | 1 + .../ConnectionTypesTableRow.tsx | 1 + .../ManageConnectionTypeFieldsTableRow.tsx | 1 + .../src/pages/groupSettings/GroupSettings.tsx | 2 + .../learningCenter/LearningCenterDataView.tsx | 1 + .../learningCenter/LearningCenterToolbar.tsx | 1 + .../screens/ModelPropertiesTableRow.tsx | 1 + .../ModelVersionDetailsHeaderActions.tsx | 2 +- .../ModelVersions/ModelVersionListView.tsx | 1 + .../ModelVersionsHeaderActions.tsx | 2 +- .../ModelVersions/ModelVersionsTableRow.tsx | 2 +- .../RegisterModel/ConnectionDropdown.tsx | 1 + .../RegisteredModelTableRow.tsx | 2 +- .../ModelRegistriesTableRow.tsx | 1 + .../CustomServingRuntimeTableRow.tsx | 1 + .../global/InferenceServiceTableRow.tsx | 1 + .../metrics/performance/PerformanceTab.tsx | 1 + .../ConnectionSection.tsx | 1 + .../DataConnectionExistingField.tsx | 1 + .../InferenceServiceFrameworkSection.tsx | 1 + .../InferenceServiceServingRuntimeSection.tsx | 1 + .../InferenceServiceModal/ProjectSelector.tsx | 1 + .../ServingRuntimeTableRow.tsx | 1 + .../ServingRuntimeTemplateSection.tsx | 1 + .../screens/admin/NotebookActions.tsx | 2 +- .../notebook/ConnectedNotebookField.tsx | 2 + .../notebook/NotebookActionsColumn.tsx | 1 + .../DataConnectionsTableRow.tsx | 1 + .../detail/storage/StorageTableRow.tsx | 2 +- .../screens/projects/EmptyProjects.tsx | 1 + .../screens/projects/ProjectTableRow.tsx | 5 ++- .../screens/spawner/EditSpawnerPage.tsx | 1 + .../connections/SelectConnectionsModal.tsx | 1 + .../__tests__/ConnectionsFormSection.spec.tsx | 12 +++--- .../ExistingDataConnectionField.tsx | 1 + .../imageSelector/ImageStreamSelector.tsx | 1 + .../imageSelector/ImageVersionSelector.tsx | 1 + .../storage/CreateNewStorageSection.tsx | 3 +- .../spawner/storage/StorageClassSelect.tsx | 6 +-- .../storageClasses/StorageClassesTableRow.tsx | 1 + 102 files changed, 370 insertions(+), 147 deletions(-) diff --git a/frontend/src/__tests__/cypress/cypress/pages/clusterStorage.ts b/frontend/src/__tests__/cypress/cypress/pages/clusterStorage.ts index d87255a01e..a3a1afceb7 100644 --- a/frontend/src/__tests__/cypress/cypress/pages/clusterStorage.ts +++ b/frontend/src/__tests__/cypress/cypress/pages/clusterStorage.ts @@ -61,6 +61,10 @@ class ClusterStorageModal extends Modal { .findByRole('button', { name: 'Typeahead menu toggle', hidden: true }); } + findWorkbenchConnectionOption(name: string) { + return cy.get('#connected-notebook-select').findByText(name); + } + findMountField() { return this.find().findByTestId('mount-path-folder-value'); } @@ -127,6 +131,10 @@ class ClusterStorageModal extends Modal { return this.find().findByTestId('storage-classes-selector'); } + findStorageClassOption(name: string) { + return cy.get('#storage-classes-selector').findByText(name); + } + findStorageClassDeprecatedWarning() { return this.find().findByTestId('deprecated-storage-warning'); } diff --git a/frontend/src/__tests__/cypress/cypress/pages/components/Pagination.ts b/frontend/src/__tests__/cypress/cypress/pages/components/Pagination.ts index 574cb0c241..570aa162d5 100644 --- a/frontend/src/__tests__/cypress/cypress/pages/components/Pagination.ts +++ b/frontend/src/__tests__/cypress/cypress/pages/components/Pagination.ts @@ -34,7 +34,7 @@ class Pagination { } selectToggleOption(name: string) { - return this.findMenuToggleButton().parents().findByRole('menuitem', { name }).click(); + return this.findMenuToggleButton().parents().parents().findByRole('menuitem', { name }).click(); } } diff --git a/frontend/src/__tests__/cypress/cypress/pages/components/table.ts b/frontend/src/__tests__/cypress/cypress/pages/components/table.ts index 7915e8d252..5fc8b8751b 100644 --- a/frontend/src/__tests__/cypress/cypress/pages/components/table.ts +++ b/frontend/src/__tests__/cypress/cypress/pages/components/table.ts @@ -20,6 +20,10 @@ export class TableRow extends Contextual { return this.find().findKebabAction(name); } + findKebabActionByMenuId(name: string, menuId: string): Cypress.Chainable> { + return this.find().findKebabActionByMenuId(name, menuId); + } + findKebab(): Cypress.Chainable> { return this.find().findKebab(); } diff --git a/frontend/src/__tests__/cypress/cypress/pages/connectionTypes.ts b/frontend/src/__tests__/cypress/cypress/pages/connectionTypes.ts index e1f63f399f..cc46495a6f 100644 --- a/frontend/src/__tests__/cypress/cypress/pages/connectionTypes.ts +++ b/frontend/src/__tests__/cypress/cypress/pages/connectionTypes.ts @@ -254,7 +254,7 @@ class ConnectionTypesPage { } findEmptyFilterResults() { - return cy.findByTestId('no-result-found-title'); + return cy.findByTestId('dashboard-empty-table-state'); } findSortButton(name: string) { diff --git a/frontend/src/__tests__/cypress/cypress/pages/modelServing.ts b/frontend/src/__tests__/cypress/cypress/pages/modelServing.ts index 210b309aef..92d4cb9349 100644 --- a/frontend/src/__tests__/cypress/cypress/pages/modelServing.ts +++ b/frontend/src/__tests__/cypress/cypress/pages/modelServing.ts @@ -66,7 +66,7 @@ class ModelServingGlobal { } findEmptyResults() { - return cy.findByTestId('no-result-found-title'); + return cy.findByTestId('dashboard-empty-table-state'); } findSortButton(name: string) { diff --git a/frontend/src/__tests__/cypress/cypress/pages/notebookImageSettings.ts b/frontend/src/__tests__/cypress/cypress/pages/notebookImageSettings.ts index 3cef8c1982..f0f738de1c 100644 --- a/frontend/src/__tests__/cypress/cypress/pages/notebookImageSettings.ts +++ b/frontend/src/__tests__/cypress/cypress/pages/notebookImageSettings.ts @@ -47,7 +47,7 @@ class NotebookImageSettings { } findEmptyResults() { - return cy.findByTestId('no-result-found-title'); + return cy.findByTestId('dashboard-empty-table-state'); } private findTable() { diff --git a/frontend/src/__tests__/cypress/cypress/pages/pipelines/compareRuns.ts b/frontend/src/__tests__/cypress/cypress/pages/pipelines/compareRuns.ts index b7cec99bb3..3fec20f604 100644 --- a/frontend/src/__tests__/cypress/cypress/pages/pipelines/compareRuns.ts +++ b/frontend/src/__tests__/cypress/cypress/pages/pipelines/compareRuns.ts @@ -115,7 +115,7 @@ class CompareRunsRocCurve extends Contextual { } findRocCurveTableEmptyState() { - return this.find().findByTestId('no-result-found-title'); + return this.find().findByTestId('dashboard-empty-table-state'); } getRocCurveRowByName(name: string) { diff --git a/frontend/src/__tests__/cypress/cypress/pages/pipelines/pipelineRunTable.ts b/frontend/src/__tests__/cypress/cypress/pages/pipelines/pipelineRunTable.ts index 35bd77361e..f16907c42d 100644 --- a/frontend/src/__tests__/cypress/cypress/pages/pipelines/pipelineRunTable.ts +++ b/frontend/src/__tests__/cypress/cypress/pages/pipelines/pipelineRunTable.ts @@ -72,7 +72,7 @@ class PipelineRunsTable { } findEmptyResults() { - return cy.findByTestId('no-result-found-title'); + return cy.findByTestId('dashboard-empty-table-state'); } mockRestoreRun(runId: string, namespace: string) { diff --git a/frontend/src/__tests__/cypress/cypress/pages/pipelines/pipelinesTable.ts b/frontend/src/__tests__/cypress/cypress/pages/pipelines/pipelinesTable.ts index cb1760db53..fbc854f43b 100644 --- a/frontend/src/__tests__/cypress/cypress/pages/pipelines/pipelinesTable.ts +++ b/frontend/src/__tests__/cypress/cypress/pages/pipelines/pipelinesTable.ts @@ -191,7 +191,7 @@ class PipelinesTable { } findEmptyResults() { - return cy.findByTestId('no-result-found-title'); + return cy.findByTestId('dashboard-empty-table-state'); } mockDeletePipeline(pipeline: PipelineKF, namespace: string) { diff --git a/frontend/src/__tests__/cypress/cypress/pages/projects.ts b/frontend/src/__tests__/cypress/cypress/pages/projects.ts index 14b4d9bacf..c991103448 100644 --- a/frontend/src/__tests__/cypress/cypress/pages/projects.ts +++ b/frontend/src/__tests__/cypress/cypress/pages/projects.ts @@ -30,7 +30,7 @@ class NotebookRow extends TableRow { } shouldHaveNotebookImageName(name: string) { - return cy.findByTestId('image-display-name').should('have.text', name); + return cy.findByTestId('image-display-name').should('contain.text', name); } findOutdatedElyraInfo() { @@ -66,7 +66,7 @@ class ProjectRow extends TableRow { } findNotebookColumnExpander() { - return this.find().findByTestId('notebook-column-count'); + return this.find().get('#expand-table-row-1-1'); } findNotebookTable() { @@ -134,7 +134,7 @@ class ProjectListPage { } findEmptyResults() { - return cy.findByTestId('no-result-found-title'); + return cy.findByTestId('dashboard-empty-table-state'); } findSortButton(name: string) { diff --git a/frontend/src/__tests__/cypress/cypress/pages/userManagement.ts b/frontend/src/__tests__/cypress/cypress/pages/userManagement.ts index 232b4b772d..aed2c8cef5 100644 --- a/frontend/src/__tests__/cypress/cypress/pages/userManagement.ts +++ b/frontend/src/__tests__/cypress/cypress/pages/userManagement.ts @@ -30,7 +30,7 @@ class GroupSettingSection extends Contextual { removeChipItem(name: string) { this.findChipGroup() .find('li') - .findByRole('button', { name: `close ${name}` }) + .findByRole('button', { name: `Close ${name}` }) .click(); } diff --git a/frontend/src/__tests__/cypress/cypress/pages/workbench.ts b/frontend/src/__tests__/cypress/cypress/pages/workbench.ts index a4dcd3c7e3..1822273b76 100644 --- a/frontend/src/__tests__/cypress/cypress/pages/workbench.ts +++ b/frontend/src/__tests__/cypress/cypress/pages/workbench.ts @@ -193,7 +193,7 @@ class AttachConnectionModal extends Modal { selectConnectionOption(name: string) { this.find().findByRole('button', { name: 'Connections' }).click(); - this.find().findByRole('option', { name }).click(); + cy.get('#select-connection').findByRole('option', { name }).click(); this.find().findByRole('button', { name: 'Connections' }).click(); } @@ -332,7 +332,7 @@ class CreateSpawnerPage { cy.findByTestId('data-connection-group') .findByRole('button', { name: 'Typeahead menu toggle' }) .click(); - cy.get('[id="dashboard-page-main"]').findByRole('option', { name }).click(); + cy.get('#select-connection').findByRole('option', { name }).click(); } findAwsNameInput() { @@ -423,7 +423,7 @@ class NotFoundSpawnerPage { } shouldHaveErrorMessageTitle(name: string) { - cy.findByTestId('error-message-title').should('have.text', name); + cy.findByTestId('error-message-title').should('contain.text', name); return this; } diff --git a/frontend/src/__tests__/cypress/cypress/support/commands/application.ts b/frontend/src/__tests__/cypress/cypress/support/commands/application.ts index a1895d9e9d..0c399166ad 100644 --- a/frontend/src/__tests__/cypress/cypress/support/commands/application.ts +++ b/frontend/src/__tests__/cypress/cypress/support/commands/application.ts @@ -38,6 +38,18 @@ declare global { isDropdownToggle?: boolean, ) => Cypress.Chainable; + /** + * Finds a patternfly kebab toggle button, opens the menu, and finds the action. + * + * @param name the name of the action in the kebeb menu + * @param isDropdownToggle - True to indicate that it is a dropdown toggle instead of table kebab actions + */ + findKebabActionByMenuId: ( + name: string | RegExp, + menuId: string, + isDropdownToggle?: boolean, + ) => Cypress.Chainable; + /** * Finds a patternfly dropdown item by first opening the dropdown if not already opened. * @@ -202,6 +214,23 @@ Cypress.Commands.add( }, ); +Cypress.Commands.add( + 'findKebabActionByMenuId', + { prevSubject: 'element' }, + (subject, name, menuId, isDropdownToggle) => { + Cypress.log({ displayName: 'findKebabByMenuId', message: name }); + return cy + .wrap(subject) + .findKebab(isDropdownToggle) + .then(($el) => { + if ($el.attr('aria-expanded') === 'false') { + cy.wrap($el).click(); + } + return cy.get(`#${menuId}`).findByRole('menuitem', { name }); + }); + }, +); + Cypress.Commands.add('findDropdownItem', { prevSubject: 'element' }, (subject, name) => { Cypress.log({ displayName: 'findDropdownItem', message: name }); return cy.wrap(subject).then(($el) => { diff --git a/frontend/src/__tests__/cypress/cypress/tests/mocked/acceleratorProfiles/acceleratorProfiles.cy.ts b/frontend/src/__tests__/cypress/cypress/tests/mocked/acceleratorProfiles/acceleratorProfiles.cy.ts index 2b8a48c3e6..c53e0a0b61 100644 --- a/frontend/src/__tests__/cypress/cypress/tests/mocked/acceleratorProfiles/acceleratorProfiles.cy.ts +++ b/frontend/src/__tests__/cypress/cypress/tests/mocked/acceleratorProfiles/acceleratorProfiles.cy.ts @@ -122,7 +122,10 @@ describe('Accelerator Profile', () => { { success: true }, ).as('delete'); acceleratorProfile.visit(); - acceleratorProfile.getRow('TensorRT').findKebabAction('Delete').click(); + acceleratorProfile + .getRow('TensorRT') + .findKebabActionByMenuId('Delete', 'accelerator-profile-actions') + .click(); deleteModal.findSubmitButton().should('be.disabled'); deleteModal.findInput().fill('TensorRT'); deleteModal.findSubmitButton().should('be.enabled').click(); diff --git a/frontend/src/__tests__/cypress/cypress/tests/mocked/acceleratorProfiles/manageAcceleratorProfiles.cy.ts b/frontend/src/__tests__/cypress/cypress/tests/mocked/acceleratorProfiles/manageAcceleratorProfiles.cy.ts index 1b11742620..c5045bc919 100644 --- a/frontend/src/__tests__/cypress/cypress/tests/mocked/acceleratorProfiles/manageAcceleratorProfiles.cy.ts +++ b/frontend/src/__tests__/cypress/cypress/tests/mocked/acceleratorProfiles/manageAcceleratorProfiles.cy.ts @@ -124,26 +124,29 @@ describe('Manage Accelerator Profile', () => { // test edit toleration let tableRow = createAcceleratorProfile.getRow('test-key'); - tableRow.findKebabAction('Edit').click(); + tableRow.findKebabActionByMenuId('Edit', 'toleration-actions').click(); editTolerationModal.findTolerationKeyInput().fill('test-update'); editTolerationModal.findCancelButton().click(); createAcceleratorProfile.getRow('test-key'); - tableRow.findKebabAction('Edit').click(); + tableRow.findKebabActionByMenuId('Edit', 'toleration-actions').click(); editTolerationModal.findTolerationKeyInput().fill('updated-test'); editTolerationModal.findTolerationSubmitButton().click(); tableRow = createAcceleratorProfile.getRow('updated-test'); tableRow.shouldHaveOperator('Equal'); // test cancel clears fields - tableRow.findKebabAction('Edit').click(); + tableRow.findKebabActionByMenuId('Edit', 'toleration-actions').click(); editTolerationModal.findCancelButton().click(); createAcceleratorProfile.findTolerationsButton().click(); createTolerationModal.findTolerationSubmitButton().should('be.disabled'); createTolerationModal.findCancelButton().click(); // test delete - tableRow.findKebabAction('Delete').click(); - createAcceleratorProfile.getRow('toleration-key').findKebabAction('Delete').click(); + tableRow.findKebabActionByMenuId('Delete', 'toleration-actions').click(); + createAcceleratorProfile + .getRow('toleration-key') + .findKebabActionByMenuId('Delete', 'toleration-actions') + .click(); createAcceleratorProfile.shouldHaveModalEmptyState(); cy.interceptOdh('POST /api/accelerator-profiles', { success: true }).as('createAccelerator'); createAcceleratorProfile.findSubmitButton().click(); diff --git a/frontend/src/__tests__/cypress/cypress/tests/mocked/applications/administration.cy.ts b/frontend/src/__tests__/cypress/cypress/tests/mocked/applications/administration.cy.ts index a9269e393c..f35dd05131 100644 --- a/frontend/src/__tests__/cypress/cypress/tests/mocked/applications/administration.cy.ts +++ b/frontend/src/__tests__/cypress/cypress/tests/mocked/applications/administration.cy.ts @@ -137,7 +137,7 @@ describe('Administration Tab', () => { userRow.shouldHavePrivilege('User'); userRow.shouldHaveLastActivity('Just now'); userRow.findServerStatusButton().should('have.text', 'View server'); - userRow.findKebabAction('Stop server').click(); + userRow.findKebabActionByMenuId('Stop server', 'notebook-actions').click(); stopNotebookModal.findStopNotebookServerButton().should('be.enabled'); stopNotebookModal.findStopNotebookServerButton().click(); diff --git a/frontend/src/__tests__/cypress/cypress/tests/mocked/connectionTypes/connectionTypes.cy.ts b/frontend/src/__tests__/cypress/cypress/tests/mocked/connectionTypes/connectionTypes.cy.ts index a98bd7c7ee..06b073dfa8 100644 --- a/frontend/src/__tests__/cypress/cypress/tests/mocked/connectionTypes/connectionTypes.cy.ts +++ b/frontend/src/__tests__/cypress/cypress/tests/mocked/connectionTypes/connectionTypes.cy.ts @@ -95,7 +95,7 @@ describe('Connection types', () => { row2.shouldBeDisabled(); row2.findConnectionTypeCompatibility().should('have.text', 'S3 compatible object storage'); - row2.findKebabAction('Preview').click(); + row2.findKebabActionByMenuId('Preview', 'connection-type-actions').click(); connectionTypePreviewModal.shouldBeOpen(); connectionTypePreviewModal.findCloseButton().click(); connectionTypePreviewModal.shouldBeOpen(false); @@ -124,7 +124,10 @@ describe('Connection types', () => { }), ]); - connectionTypesPage.getConnectionTypeRow('Test display name').findKebabAction('Delete').click(); + connectionTypesPage + .getConnectionTypeRow('Test display name') + .findKebabActionByMenuId('Delete', 'connection-type-actions') + .click(); deleteModal.findSubmitButton().should('be.disabled'); deleteModal.findInput().fill('Test display name'); deleteModal.findSubmitButton().should('be.enabled').click(); diff --git a/frontend/src/__tests__/cypress/cypress/tests/mocked/connectionTypes/createConnectionType.cy.ts b/frontend/src/__tests__/cypress/cypress/tests/mocked/connectionTypes/createConnectionType.cy.ts index 266ce99db9..eec3eea4a3 100644 --- a/frontend/src/__tests__/cypress/cypress/tests/mocked/connectionTypes/createConnectionType.cy.ts +++ b/frontend/src/__tests__/cypress/cypress/tests/mocked/connectionTypes/createConnectionType.cy.ts @@ -289,7 +289,7 @@ describe('edit', () => { createConnectionTypePage .getFieldsTableRow(4) - .findKebabAction('Move to section heading') + .findKebabActionByMenuId('Move to section heading', 'connection-type-field-actions') .click(); // move to default which is the first section cy.findByTestId('section-heading-select').should('be.disabled'); @@ -304,7 +304,7 @@ describe('edit', () => { createConnectionTypePage .getFieldsTableRow(0) - .findKebabAction('Move to section heading') + .findKebabActionByMenuId('Move to section heading', 'connection-type-field-actions') .click(); cy.findByTestId('section-heading-select').click(); cy.findByTestId('section-heading-select').findSelectOption('header2').click(); diff --git a/frontend/src/__tests__/cypress/cypress/tests/mocked/customServingRuntimes/customServingRuntimes.cy.ts b/frontend/src/__tests__/cypress/cypress/tests/mocked/customServingRuntimes/customServingRuntimes.cy.ts index 078bffb27a..75fba8e1f3 100644 --- a/frontend/src/__tests__/cypress/cypress/tests/mocked/customServingRuntimes/customServingRuntimes.cy.ts +++ b/frontend/src/__tests__/cypress/cypress/tests/mocked/customServingRuntimes/customServingRuntimes.cy.ts @@ -209,7 +209,11 @@ describe('Custom serving runtimes', () => { 'duplicateTemplate', ); - servingRuntimes.getRowById('template-1').find().findKebabAction('Duplicate').click(); + servingRuntimes + .getRowById('template-1') + .find() + .findKebabActionByMenuId('Duplicate', 'custom-serving-runtime-actions') + .click(); servingRuntimes.findAppTitle().should('have.text', 'Duplicate serving runtime'); cy.url().should('include', '/addServingRuntime'); @@ -276,7 +280,11 @@ describe('Custom serving runtimes', () => { mockServingRuntimeTemplateK8sResource({}), ).as('editTemplate'); - servingRuntimes.getRowById('template-1').find().findKebabAction('Edit').click(); + servingRuntimes + .getRowById('template-1') + .find() + .findKebabActionByMenuId('Edit', 'custom-serving-runtime-actions') + .click(); servingRuntimes.findAppTitle().should('contain', 'Edit Multi Platform'); cy.url().should('include', '/editServingRuntime/template-1'); servingRuntimes.findSubmitButton().should('be.disabled'); @@ -323,7 +331,11 @@ describe('Custom serving runtimes', () => { mockServingRuntimeTemplateK8sResource({}), ).as('deleteServingRuntime'); - servingRuntimes.getRowById('template-1').find().findKebabAction('Delete').click(); + servingRuntimes + .getRowById('template-1') + .find() + .findKebabActionByMenuId('Delete', 'custom-serving-runtime-actions') + .click(); deleteModal.findSubmitButton().should('be.disabled'); // test delete form is enabled after filling out required fields diff --git a/frontend/src/__tests__/cypress/cypress/tests/mocked/modelRegistry/modelVersionArchive.cy.ts b/frontend/src/__tests__/cypress/cypress/tests/mocked/modelRegistry/modelVersionArchive.cy.ts index 043f3aac44..a90d9639d9 100644 --- a/frontend/src/__tests__/cypress/cypress/tests/mocked/modelRegistry/modelVersionArchive.cy.ts +++ b/frontend/src/__tests__/cypress/cypress/tests/mocked/modelRegistry/modelVersionArchive.cy.ts @@ -239,7 +239,9 @@ describe('Restoring archive version', () => { modelVersionArchive.visit(); const archiveVersionRow = modelVersionArchive.getRow('model version 2'); - archiveVersionRow.findKebabAction('Restore model version').click(); + archiveVersionRow + .findKebabActionByMenuId('Restore model version', 'model-version-actions') + .click(); restoreVersionModal.findRestoreButton().click(); @@ -295,7 +297,9 @@ describe('Archiving version', () => { modelVersionArchive.visitModelVersionList(); const modelVersionRow = modelRegistry.getModelVersionRow('model version 3'); - modelVersionRow.findKebabAction('Archive model version').click(); + modelVersionRow + .findKebabActionByMenuId('Archive model version', 'model-version-actions') + .click(); archiveVersionModal.findArchiveButton().should('be.disabled'); archiveVersionModal.findModalTextInput().fill('model version 3'); archiveVersionModal.findArchiveButton().should('be.enabled').click(); @@ -338,7 +342,9 @@ describe('Archiving version', () => { modelVersionArchive.visitModelVersionList(); const modelVersionRow = modelRegistry.getModelVersionRow('model version 3'); - modelVersionRow.findKebabAction('Archive model version').should('have.attr', 'aria-disabled'); + modelVersionRow + .findKebabActionByMenuId('Archive model version', 'model-version-actions') + .should('have.attr', 'aria-disabled'); }); it('Cannot archive model that has versions with a deployment', () => { diff --git a/frontend/src/__tests__/cypress/cypress/tests/mocked/modelRegistry/modelVersionDeploy.cy.ts b/frontend/src/__tests__/cypress/cypress/tests/mocked/modelRegistry/modelVersionDeploy.cy.ts index 0da372fceb..a97d3af96a 100644 --- a/frontend/src/__tests__/cypress/cypress/tests/mocked/modelRegistry/modelVersionDeploy.cy.ts +++ b/frontend/src/__tests__/cypress/cypress/tests/mocked/modelRegistry/modelVersionDeploy.cy.ts @@ -184,7 +184,7 @@ describe('Deploy model version', () => { initIntercepts({ kServeInstalled: false, modelMeshInstalled: false }); cy.visit(`/modelRegistry/modelregistry-sample/registeredModels/1/versions`); const modelVersionRow = modelRegistry.getModelVersionRow('test model version'); - modelVersionRow.findKebabAction('Deploy').click(); + modelVersionRow.findKebabActionByMenuId('Deploy', 'model-version-actions').click(); modelVersionDeployModal.selectProjectByName('Model mesh project'); cy.findByText('Multi-model platform is not installed').should('exist'); modelVersionDeployModal.selectProjectByName('KServe project'); @@ -195,7 +195,7 @@ describe('Deploy model version', () => { initIntercepts({}); cy.visit(`/modelRegistry/modelregistry-sample/registeredModels/1/versions`); const modelVersionRow = modelRegistry.getModelVersionRow('test model version'); - modelVersionRow.findKebabAction('Deploy').click(); + modelVersionRow.findKebabActionByMenuId('Deploy', 'model-version-actions').click(); modelVersionDeployModal.selectProjectByName('Test project'); cy.findByText('Cannot deploy the model until you select a model serving platform').should( 'exist', @@ -206,7 +206,7 @@ describe('Deploy model version', () => { initIntercepts({}); cy.visit(`/modelRegistry/modelregistry-sample/registeredModels/1/versions`); const modelVersionRow = modelRegistry.getModelVersionRow('test model version'); - modelVersionRow.findKebabAction('Deploy').click(); + modelVersionRow.findKebabActionByMenuId('Deploy', 'model-version-actions').click(); cy.interceptK8sList(ServingRuntimeModel, mockK8sResourceList([])); modelVersionDeployModal.selectProjectByName('Model mesh project'); cy.findByText('Cannot deploy the model until you configure a model server').should('exist'); @@ -229,7 +229,7 @@ describe('Deploy model version', () => { ); cy.visit(`/modelRegistry/modelregistry-sample/registeredModels/1/versions`); const modelVersionRow = modelRegistry.getModelVersionRow('test model version'); - modelVersionRow.findKebabAction('Deploy').click(); + modelVersionRow.findKebabActionByMenuId('Deploy', 'model-version-actions').click(); modelVersionDeployModal.selectProjectByName('KServe project'); // Validate name input field @@ -282,7 +282,7 @@ describe('Deploy model version', () => { cy.visit(`/modelRegistry/modelregistry-sample/registeredModels/1/versions`); const modelVersionRow = modelRegistry.getModelVersionRow('test model version'); - modelVersionRow.findKebabAction('Deploy').click(); + modelVersionRow.findKebabActionByMenuId('Deploy', 'model-version-actions').click(); modelVersionDeployModal.selectProjectByName('KServe project'); // Validate data connection section @@ -323,7 +323,7 @@ describe('Deploy model version', () => { cy.visit(`/modelRegistry/modelregistry-sample/registeredModels/1/versions`); const modelVersionRow = modelRegistry.getModelVersionRow('test model version'); - modelVersionRow.findKebabAction('Deploy').click(); + modelVersionRow.findKebabActionByMenuId('Deploy', 'model-version-actions').click(); modelVersionDeployModal.selectProjectByName('KServe project'); // Validate data connection section diff --git a/frontend/src/__tests__/cypress/cypress/tests/mocked/modelRegistry/modelVersionDetails.cy.ts b/frontend/src/__tests__/cypress/cypress/tests/mocked/modelRegistry/modelVersionDetails.cy.ts index d9453f156a..5d134ef62a 100644 --- a/frontend/src/__tests__/cypress/cypress/tests/mocked/modelRegistry/modelVersionDetails.cy.ts +++ b/frontend/src/__tests__/cypress/cypress/tests/mocked/modelRegistry/modelVersionDetails.cy.ts @@ -274,12 +274,12 @@ describe('Model version details', () => { modelVersionDetails.findExpandControlButton().should('have.text', 'Show 2 more properties'); modelVersionDetails.findExpandControlButton().click(); const propertyRow = modelVersionDetails.getRow('a6'); - propertyRow.find().findKebabAction('Edit').click(); + propertyRow.find().findKebabActionByMenuId('Edit', 'model-properties-actions').click(); modelVersionDetails.findKeyEditInput('a6').clear().type('edit_key'); modelVersionDetails.findValueEditInput('v1').clear().type('edit_value'); modelVersionDetails.findCancelButton().click(); - propertyRow.find().findKebabAction('Edit').click(); + propertyRow.find().findKebabActionByMenuId('Edit', 'model-properties-actions').click(); modelVersionDetails.findKeyEditInput('a6').clear().type('edit_key'); modelVersionDetails.findValueEditInput('v1').clear().type('edit_value'); modelVersionDetails.findSaveButton().click(); @@ -313,7 +313,7 @@ describe('Model version details', () => { modelVersionDetails.findExpandControlButton().click(); const propertyRow = modelVersionDetails.getRow('a6'); modelVersionDetails.findPropertiesTableRows().should('have.length', 7); - propertyRow.find().findKebabAction('Delete').click(); + propertyRow.find().findKebabActionByMenuId('Delete', 'model-properties-actions').click(); cy.wait('@UpdatePropertyRow').then((interception) => { expect(interception.request.body).to.eql({ customProperties: { diff --git a/frontend/src/__tests__/cypress/cypress/tests/mocked/modelRegistry/registeredModelArchive.cy.ts b/frontend/src/__tests__/cypress/cypress/tests/mocked/modelRegistry/registeredModelArchive.cy.ts index b638f50222..305288a786 100644 --- a/frontend/src/__tests__/cypress/cypress/tests/mocked/modelRegistry/registeredModelArchive.cy.ts +++ b/frontend/src/__tests__/cypress/cypress/tests/mocked/modelRegistry/registeredModelArchive.cy.ts @@ -269,7 +269,7 @@ it('Opens the detail page when we select "View Details" from action menu', () => initIntercepts({}); registeredModelArchive.visit(); const archiveModelRow = registeredModelArchive.getRow('model 2'); - archiveModelRow.findKebabAction('View details').click(); + archiveModelRow.findKebabActionByMenuId('View details', 'registered-modal-actions').click(); cy.location('pathname').should( 'be.equals', '/modelRegistry/modelregistry-sample/registeredModels/archive/2/details', @@ -294,7 +294,7 @@ describe('Restoring archive model', () => { registeredModelArchive.visit(); const archiveModelRow = registeredModelArchive.getRow('model 2'); - archiveModelRow.findKebabAction('Restore model').click(); + archiveModelRow.findKebabActionByMenuId('Restore model', 'registered-modal-actions').click(); restoreModelModal.findRestoreButton().click(); @@ -350,7 +350,7 @@ describe('Archiving model', () => { registeredModelArchive.visitModelList(); const modelRow = modelRegistry.getRow('model 3'); - modelRow.findKebabAction('Archive model').click(); + modelRow.findKebabActionByMenuId('Archive model', 'registered-modal-actions').click(); archiveModelModal.findArchiveButton().should('be.disabled'); archiveModelModal.findModalTextInput().fill('model 3'); archiveModelModal.findArchiveButton().should('be.enabled').click(); diff --git a/frontend/src/__tests__/cypress/cypress/tests/mocked/modelRegistrySettings/modelRegistryPermissions.cy.ts b/frontend/src/__tests__/cypress/cypress/tests/mocked/modelRegistrySettings/modelRegistryPermissions.cy.ts index 586070c0a8..b43ea47dba 100644 --- a/frontend/src/__tests__/cypress/cypress/tests/mocked/modelRegistrySettings/modelRegistryPermissions.cy.ts +++ b/frontend/src/__tests__/cypress/cypress/tests/mocked/modelRegistrySettings/modelRegistryPermissions.cy.ts @@ -215,7 +215,10 @@ describe('MR Permissions', () => { modelRegistryPermissions.visit('example-mr'); - userTable.getTableRow('example-mr-user').findKebabAction('Edit').click(); + userTable + .getTableRow('example-mr-user') + .findKebabActionByMenuId('Edit', 'role-bindings-permissions-actions') + .click(); userTable.findEditInput('example-mr-user').clear().type('edited-user'); userTable.findEditSaveButton('edited-user').click(); @@ -253,7 +256,10 @@ describe('MR Permissions', () => { modelRegistryPermissions.visit('example-mr'); - userTable.getTableRow('example-mr-user').findKebabAction('Delete').click(); + userTable + .getTableRow('example-mr-user') + .findKebabActionByMenuId('Delete', 'role-bindings-permissions-actions') + .click(); cy.wait('@deleteUser'); }); @@ -344,7 +350,10 @@ describe('MR Permissions', () => { modelRegistryPermissions.visit('example-mr'); - groupTable.getTableRow('example-mr-users-2').findKebabAction('Edit').click(); + groupTable + .getTableRow('example-mr-users-2') + .findKebabActionByMenuId('Edit', 'role-bindings-permissions-actions') + .click(); groupTable.findNameSelect().clear().type('example-mr-group-opti'); cy.findByText('example-mr-group-option').click(); groupTable.findEditSaveButton('example-mr-group-option').click(); @@ -388,7 +397,10 @@ describe('MR Permissions', () => { ).as('deleteGroup'); modelRegistryPermissions.visit('example-mr'); - groupTable.getTableRow('example-mr-users-2').findKebabAction('Delete').click(); + groupTable + .getTableRow('example-mr-users-2') + .findKebabActionByMenuId('Delete', 'role-bindings-permissions-actions') + .click(); cy.wait('@deleteGroup'); }); @@ -492,7 +504,10 @@ describe('MR Permissions', () => { mock200Status({}), ).as('deleteProject'); - projectTable.getTableRow('Test Project').findKebabAction('Edit').click(); + projectTable + .getTableRow('Test Project') + .findKebabActionByMenuId('Edit', 'role-bindings-permissions-actions') + .click(); projectTable.findNameSelect().findSelectOption('Project').click(); projectTable.findEditSaveButton('Project').click(); @@ -521,7 +536,10 @@ describe('MR Permissions', () => { { path: { name: 'test-name-view' } }, mock200Status({}), ).as('deleteProject'); - projectTable.getTableRow('Test Project').findKebabAction('Delete').click(); + projectTable + .getTableRow('Test Project') + .findKebabActionByMenuId('Delete', 'role-bindings-permissions-actions') + .click(); cy.wait('@deleteProject'); }); }); diff --git a/frontend/src/__tests__/cypress/cypress/tests/mocked/modelRegistrySettings/modelRegistrySettings.cy.ts b/frontend/src/__tests__/cypress/cypress/tests/mocked/modelRegistrySettings/modelRegistrySettings.cy.ts index a9e907203f..4e4f5e780a 100644 --- a/frontend/src/__tests__/cypress/cypress/tests/mocked/modelRegistrySettings/modelRegistrySettings.cy.ts +++ b/frontend/src/__tests__/cypress/cypress/tests/mocked/modelRegistrySettings/modelRegistrySettings.cy.ts @@ -182,7 +182,7 @@ describe('ViewDatabaseConfigModal', () => { modelRegistrySettings.visit(true); modelRegistrySettings .findModelRegistryRow('test-registry-1') - .findKebabAction('View database configuration') + .findKebabActionByMenuId('View database configuration', 'model-registry-actions') .click(); modelRegistrySettings .findDatabaseDetail(DatabaseDetailsTestId.HOST) @@ -207,7 +207,7 @@ describe('ViewDatabaseConfigModal', () => { modelRegistrySettings.visit(true); modelRegistrySettings .findModelRegistryRow('test-registry-2') - .findKebabAction('View database configuration') + .findKebabActionByMenuId('View database configuration', 'model-registry-actions') .click(); cy.findByText('Error loading password').should('exist'); }); @@ -241,7 +241,7 @@ describe('DeleteModelRegistryModal', () => { modelRegistrySettings.visit(true); modelRegistrySettings .findModelRegistryRow('test-registry-1') - .findKebabAction('Delete model registry') + .findKebabActionByMenuId('Delete model registry', 'model-registry-actions') .click(); }); diff --git a/frontend/src/__tests__/cypress/cypress/tests/mocked/modelServing/modelServingGlobal.cy.ts b/frontend/src/__tests__/cypress/cypress/tests/mocked/modelServing/modelServingGlobal.cy.ts index 746aaa393b..40ccfef3e1 100644 --- a/frontend/src/__tests__/cypress/cypress/tests/mocked/modelServing/modelServingGlobal.cy.ts +++ b/frontend/src/__tests__/cypress/cypress/tests/mocked/modelServing/modelServingGlobal.cy.ts @@ -236,7 +236,7 @@ describe('Model Serving Global', () => { // user flow for deleting a project modelServingGlobal .getModelRow('Test Inference Service') - .findKebabAction(/^Delete/) + .findKebabActionByMenuId(/^Delete/, 'inference-table-actions') .click(); // Test that can submit on valid form @@ -270,7 +270,10 @@ describe('Model Serving Global', () => { modelServingGlobal.visit('test-project'); // user flow for editing a project - modelServingGlobal.getModelRow('Test Inference Service').findKebabAction('Edit').click(); + modelServingGlobal + .getModelRow('Test Inference Service') + .findKebabActionByMenuId('Edit', 'inference-table-actions') + .click(); // test that you can not submit on empty inferenceServiceModalEdit.shouldBeOpen(); diff --git a/frontend/src/__tests__/cypress/cypress/tests/mocked/modelServing/modelServingNim.cy.ts b/frontend/src/__tests__/cypress/cypress/tests/mocked/modelServing/modelServingNim.cy.ts index 9098d520f5..5c949b444e 100644 --- a/frontend/src/__tests__/cypress/cypress/tests/mocked/modelServing/modelServingNim.cy.ts +++ b/frontend/src/__tests__/cypress/cypress/tests/mocked/modelServing/modelServingNim.cy.ts @@ -46,7 +46,13 @@ describe('NIM Models Deployments', () => { cy.interceptK8sList(ServingRuntimeModel, mockK8sResourceList([mockNimServingRuntime()])); modelServingGlobal.visit('test-project'); - modelServingGlobal.getModelRow('Test Name').findKebabAction('Edit').should('exist'); - modelServingGlobal.getModelRow('Test Name').findKebabAction('Delete').should('exist'); + modelServingGlobal + .getModelRow('Test Name') + .findKebabActionByMenuId('Edit', 'inference-table-actions') + .should('exist'); + modelServingGlobal + .getModelRow('Test Name') + .findKebabActionByMenuId('Delete', 'inference-table-actions') + .should('exist'); }); }); diff --git a/frontend/src/__tests__/cypress/cypress/tests/mocked/modelServing/servingRuntimeList.cy.ts b/frontend/src/__tests__/cypress/cypress/tests/mocked/modelServing/servingRuntimeList.cy.ts index 7e92609cda..f979469ed6 100644 --- a/frontend/src/__tests__/cypress/cypress/tests/mocked/modelServing/servingRuntimeList.cy.ts +++ b/frontend/src/__tests__/cypress/cypress/tests/mocked/modelServing/servingRuntimeList.cy.ts @@ -508,7 +508,10 @@ describe('Serving Runtime List', () => { .getModelMeshRow('OVMS Model Serving') .findDeployedModelExpansionButton() .click(); - modelServingSection.getInferenceServiceRow('OVMS ONNX').findKebabAction('Edit').click(); + modelServingSection + .getInferenceServiceRow('OVMS ONNX') + .findKebabActionByMenuId('Edit', 'inference-table-actions') + .click(); inferenceServiceModalEdit.shouldBeOpen(); inferenceServiceModalEdit .findServingRuntimeSelect() @@ -1013,7 +1016,11 @@ describe('Serving Runtime List', () => { projectDetails.visitSection('test-project', 'model-server'); // click on the toggle button and open edit model server - modelServingSection.getKServeRow('Llama Service').find().findKebabAction('Edit').click(); + modelServingSection + .getKServeRow('Llama Service') + .find() + .findKebabActionByMenuId('Edit', 'inference-table-actions') + .click(); kserveModalEdit.shouldBeOpen(); @@ -1195,7 +1202,10 @@ describe('Serving Runtime List', () => { mock200Status({}), ).as('deleteRoleBindings'); projectDetails.visitSection('test-project', 'model-server'); - modelServingSection.getModelMeshRow('ovms').findKebabAction('Delete model server').click(); + modelServingSection + .getModelMeshRow('ovms') + .findKebabActionByMenuId('Delete model server', 'serving-runtime-actions') + .click(); deleteModal.shouldBeOpen(); deleteModal.findSubmitButton().should('be.disabled'); @@ -1433,7 +1443,7 @@ describe('Serving Runtime List', () => { modelServingSection .getModelMeshRow('ovms') .find() - .findKebabAction('Edit model server') + .findKebabActionByMenuId('Edit model server', 'serving-runtime-actions') .click(); editServingRuntimeModal.shouldBeOpen(); @@ -2129,7 +2139,7 @@ describe('Serving Runtime List', () => { .should('contain.text', 'Small'); // click on the toggle button and open edit model server - kserveRow.find().findKebabAction('Edit').click(); + kserveRow.find().findKebabActionByMenuId('Edit', 'inference-table-actions').click(); kserveModalEdit.shouldBeOpen(); @@ -2179,7 +2189,7 @@ describe('Serving Runtime List', () => { .should('contain.text', 'Small'); // click on the toggle button and open edit model server - kserveRow.find().findKebabAction('Edit').click(); + kserveRow.find().findKebabActionByMenuId('Edit', 'inference-table-actions').click(); kserveModalEdit.shouldBeOpen(); @@ -2230,7 +2240,11 @@ describe('Serving Runtime List', () => { .should('contain.text', 'Custom'); // click on the toggle button and open edit model server - modelServingSection.getKServeRow('Llama Service').find().findKebabAction('Edit').click(); + modelServingSection + .getKServeRow('Llama Service') + .find() + .findKebabActionByMenuId('Edit', 'inference-table-actions') + .click(); kserveModalEdit.shouldBeOpen(); diff --git a/frontend/src/__tests__/cypress/cypress/tests/mocked/notebookImageSettings/notebookImageSettings.cy.ts b/frontend/src/__tests__/cypress/cypress/tests/mocked/notebookImageSettings/notebookImageSettings.cy.ts index 155bd47218..926f8b18d2 100644 --- a/frontend/src/__tests__/cypress/cypress/tests/mocked/notebookImageSettings/notebookImageSettings.cy.ts +++ b/frontend/src/__tests__/cypress/cypress/tests/mocked/notebookImageSettings/notebookImageSettings.cy.ts @@ -242,7 +242,11 @@ describe('Notebook image settings', () => { notebookImageSettings.visit(); // open edit form - notebookImageSettings.getRow('Testing Custom Image').find().findKebabAction('Edit').click(); + notebookImageSettings + .getRow('Testing Custom Image') + .find() + .findKebabActionByMenuId('Edit', 'byon-image-actions') + .click(); // test inputs have correct values updateNotebookImageModal.findImageLocationInput().should('have.value', 'test-image:latest'); @@ -289,7 +293,11 @@ describe('Notebook image settings', () => { notebookImageSettings.visit(); // test delete form is disabled initially - notebookImageSettings.getRow('Testing Custom Image').find().findKebabAction('Delete').click(); + notebookImageSettings + .getRow('Testing Custom Image') + .find() + .findKebabActionByMenuId('Delete', 'byon-image-actions') + .click(); deleteModal.findSubmitButton().should('be.disabled'); @@ -347,7 +355,11 @@ describe('Notebook image settings', () => { importNotebookImageModal.findCloseButton().click(); // edit error - notebookImageSettings.getRow('Testing Custom Image').find().findKebabAction('Edit').click(); + notebookImageSettings + .getRow('Testing Custom Image') + .find() + .findKebabActionByMenuId('Edit', 'byon-image-actions') + .click(); updateNotebookImageModal.findSubmitButton().click(); cy.wait('@editError'); @@ -356,7 +368,11 @@ describe('Notebook image settings', () => { updateNotebookImageModal.findCloseButton().click(); // delete error - notebookImageSettings.getRow('Testing Custom Image').find().findKebabAction('Delete').click(); + notebookImageSettings + .getRow('Testing Custom Image') + .find() + .findKebabActionByMenuId('Delete', 'byon-image-actions') + .click(); notebookImageDeleteModal.findInput().type('Testing Custom Image'); notebookImageDeleteModal.findSubmitButton().click(); diff --git a/frontend/src/__tests__/cypress/cypress/tests/mocked/pipelines/experiments.cy.ts b/frontend/src/__tests__/cypress/cypress/tests/mocked/pipelines/experiments.cy.ts index cf0d1932f2..f538c477ec 100644 --- a/frontend/src/__tests__/cypress/cypress/tests/mocked/pipelines/experiments.cy.ts +++ b/frontend/src/__tests__/cypress/cypress/tests/mocked/pipelines/experiments.cy.ts @@ -139,7 +139,7 @@ describe('Experiments', () => { activeExperimentsTable.mockArchiveExperiment(experimentToArchive.experiment_id, projectName); activeExperimentsTable .getRowByName(experimentToArchive.display_name) - .findKebabAction('Archive') + .findKebabActionByMenuId('Archive', 'experiment-actions') .click(); experimentsTabs.mockGetExperiments(projectName, [ @@ -202,7 +202,7 @@ describe('Experiments', () => { ); archivedExperimentsTable .getRowByName(experimentToRestore.display_name) - .findKebabAction('Restore') + .findKebabActionByMenuId('Restore', 'experiment-actions') .click(); experimentsTabs.mockGetExperiments(projectName, [ @@ -285,7 +285,7 @@ describe('Experiments', () => { activeRunsTable.getRowByName('Test active run 4').findColumnName('Test active run 4').click(); pipelineRunDetails .findErrorState('run-graph-error-state') - .should('have.text', 'Pipeline run graph unavailable'); + .should('contain.text', 'Pipeline run graph unavailable'); pipelineRunDetails.findDetailsTab().click(); pipelineRunDetails.findDetailItem('Name').findValue().contains(mockActiveRuns.display_name); @@ -302,7 +302,7 @@ describe('Experiments', () => { pipelineRunDetails.findPipelineSpecTab().click(); pipelineRunDetails .findErrorState('pipeline-spec-error-state') - .should('have.text', 'Pipeline spec unavailable'); + .should('contain.text', 'Pipeline spec unavailable'); }); it('navigates back to experiments from "Create run" page breadcrumb', () => { diff --git a/frontend/src/__tests__/cypress/cypress/tests/mocked/pipelines/pipelineCreateRuns.cy.ts b/frontend/src/__tests__/cypress/cypress/tests/mocked/pipelines/pipelineCreateRuns.cy.ts index 0df9150d5d..c02ad9522a 100644 --- a/frontend/src/__tests__/cypress/cypress/tests/mocked/pipelines/pipelineCreateRuns.cy.ts +++ b/frontend/src/__tests__/cypress/cypress/tests/mocked/pipelines/pipelineCreateRuns.cy.ts @@ -239,7 +239,10 @@ describe('Pipeline create runs', () => { // Navigate to duplicate run page for a given active run cy.visitWithLogin(`/experiments/${projectName}/experiment-1/runs`); pipelineRunsGlobal.findActiveRunsTab().click(); - activeRunsTable.getRowByName(mockRun.display_name).findKebabAction('Duplicate').click(); + activeRunsTable + .getRowByName(mockRun.display_name) + .findKebabActionByMenuId('Duplicate', 'pipeline-run-table-row-actions') + .click(); verifyRelativeURL( `/experiments/${projectName}/experiment-1/runs/duplicate/${mockRun.run_id}`, ); @@ -694,7 +697,7 @@ describe('Pipeline create runs', () => { pipelineRunsGlobal.findSchedulesTab().click(); pipelineRecurringRunTable .getRowByName(mockRecurringRun.display_name) - .findKebabAction('Duplicate') + .findKebabActionByMenuId('Duplicate', 'pipeline-recurring-run-actions') .click(); verifyRelativeURL( `/experiments/${projectName}/experiment-1/schedules/duplicate/${mockRecurringRun.recurring_run_id}`, @@ -772,7 +775,7 @@ describe('Pipeline create runs', () => { pipelineRunsGlobal.findSchedulesTab().click(); pipelineRecurringRunTable .getRowByName(mockRecurringRun.display_name) - .findKebabAction('Duplicate') + .findKebabActionByMenuId('Duplicate', 'pipeline-recurring-run-actions') .click(); verifyRelativeURL( `/experiments/${projectName}/experiment-1/schedules/duplicate/${mockRecurringRun.recurring_run_id}`, diff --git a/frontend/src/__tests__/cypress/cypress/tests/mocked/pipelines/pipelineDeleteRuns.cy.ts b/frontend/src/__tests__/cypress/cypress/tests/mocked/pipelines/pipelineDeleteRuns.cy.ts index e7f52e2f8a..8c492edd29 100644 --- a/frontend/src/__tests__/cypress/cypress/tests/mocked/pipelines/pipelineDeleteRuns.cy.ts +++ b/frontend/src/__tests__/cypress/cypress/tests/mocked/pipelines/pipelineDeleteRuns.cy.ts @@ -116,7 +116,10 @@ describe('Pipeline runs', () => { pipelineRunsGlobal.isApiAvailable(); pipelineRunsGlobal.findSchedulesTab().click(); - pipelineRecurringRunTable.getRowByName('test-pipeline').findKebabAction('Delete').click(); + pipelineRecurringRunTable + .getRowByName('test-pipeline') + .findKebabActionByMenuId('Delete', 'pipeline-recurring-run-actions') + .click(); schedulesDeleteModal.shouldBeOpen(); schedulesDeleteModal.findSubmitButton().should('be.disabled'); diff --git a/frontend/src/__tests__/cypress/cypress/tests/mocked/pipelines/pipelineRuns.cy.ts b/frontend/src/__tests__/cypress/cypress/tests/mocked/pipelines/pipelineRuns.cy.ts index f452bfc0a9..dde606731f 100644 --- a/frontend/src/__tests__/cypress/cypress/tests/mocked/pipelines/pipelineRuns.cy.ts +++ b/frontend/src/__tests__/cypress/cypress/tests/mocked/pipelines/pipelineRuns.cy.ts @@ -1001,7 +1001,7 @@ describe('Pipeline runs', () => { pipelineRunsGlobal.findSchedulesTab().click(); pipelineRecurringRunTable .getRowByName(mockRecurringRuns[0].display_name) - .findKebabAction('Duplicate') + .findKebabActionByMenuId('Duplicate', 'pipeline-recurring-run-actions') .click(); verifyRelativeURL( diff --git a/frontend/src/__tests__/cypress/cypress/tests/mocked/pipelines/pipelines.cy.ts b/frontend/src/__tests__/cypress/cypress/tests/mocked/pipelines/pipelines.cy.ts index effe3ca15d..3aed45385b 100644 --- a/frontend/src/__tests__/cypress/cypress/tests/mocked/pipelines/pipelines.cy.ts +++ b/frontend/src/__tests__/cypress/cypress/tests/mocked/pipelines/pipelines.cy.ts @@ -864,7 +864,7 @@ describe('Pipelines', () => { // Check pipeline pipelinesTable .getRowById(initialMockPipeline.pipeline_id) - .findKebabAction('Delete pipeline') + .findKebabActionByMenuId('Delete pipeline', 'pipeline-actions') .click(); pipelineDeleteModal.shouldBeOpen(); pipelineDeleteModal.findInput().type(initialMockPipeline.display_name); @@ -900,7 +900,7 @@ describe('Pipelines', () => { pipelineRow.findExpandButton().click(); pipelineRow .getPipelineVersionRowById(initialMockPipelineVersion.pipeline_version_id) - .findKebabAction('Delete pipeline version') + .findKebabActionByMenuId('Delete pipeline version', 'pipeline-version-actions') .click(); pipelineDeleteModal.shouldBeOpen(); pipelineDeleteModal.findInput().type(initialMockPipelineVersion.display_name); @@ -942,7 +942,7 @@ describe('Pipelines', () => { pipelineRow .getPipelineVersionRowById(initialMockPipelineVersion.pipeline_version_id) .findPipelineVersionLink() - .click(); + .click({ force: true }); cy.url().should( 'include', @@ -1047,7 +1047,7 @@ describe('Pipelines', () => { pipelinesTable.find(); pipelinesTable .getRowById(initialMockPipeline.pipeline_id) - .findKebabAction('Create run') + .findKebabActionByMenuId('Create run', 'pipeline-actions') .click(); cy.url().should( @@ -1094,14 +1094,22 @@ describe('Pipelines', () => { // Wait for the pipelines table to load pipelinesTable.find(); const pipelineRow = pipelinesTable.getRowById('argo-workflow'); - pipelineRow.findKebabAction('Create run').should('have.attr', 'aria-disabled'); - pipelineRow.findKebabAction('Create schedule').should('have.attr', 'aria-disabled'); + pipelineRow + .findKebabActionByMenuId('Create run', 'pipeline-actions') + .should('have.attr', 'aria-disabled'); + pipelineRow + .findKebabActionByMenuId('Create schedule', 'pipeline-actions') + .should('have.attr', 'aria-disabled'); pipelineRow.findExpandButton().click(); const pipelineVersionRow = pipelineRow.getPipelineVersionRowById('test-pipeline-version'); - pipelineVersionRow.findKebabAction('Create run').should('have.attr', 'aria-disabled'); - pipelineVersionRow.findKebabAction('Create schedule').should('have.attr', 'aria-disabled'); + pipelineVersionRow + .findKebabActionByMenuId('Create run', 'pipeline-version-actions') + .should('have.attr', 'aria-disabled'); + pipelineVersionRow + .findKebabActionByMenuId('Create schedule', 'pipeline-version-actions') + .should('have.attr', 'aria-disabled'); }); it('run and schedule dropdown action should be disabeld when pipeline has no versions', () => { @@ -1110,11 +1118,11 @@ describe('Pipelines', () => { pipelinesTable .getRowById(initialMockPipeline.pipeline_id) - .findKebabAction('Create schedule') + .findKebabActionByMenuId('Create schedule', 'pipeline-actions') .should('have.attr', 'aria-disabled'); pipelinesTable .getRowById(initialMockPipeline.pipeline_id) - .findKebabAction('Create run') + .findKebabActionByMenuId('Create run', 'pipeline-actions') .should('have.attr', 'aria-disabled'); }); @@ -1125,7 +1133,7 @@ describe('Pipelines', () => { pipelinesTable.find(); pipelinesTable .getRowById(initialMockPipeline.pipeline_id) - .findKebabAction('Create schedule') + .findKebabActionByMenuId('Create schedule', 'pipeline-actions') .click(); cy.url().should( @@ -1144,7 +1152,7 @@ describe('Pipelines', () => { pipelineRow.findExpandButton().click(); pipelineRow .getPipelineVersionRowById(initialMockPipelineVersion.pipeline_version_id) - .findKebabAction('Create run') + .findKebabActionByMenuId('Create run', 'pipeline-version-actions') .click(); cy.url().should( @@ -1162,7 +1170,7 @@ describe('Pipelines', () => { pipelineRow.findExpandButton().click(); pipelineRow .getPipelineVersionRowById(initialMockPipelineVersion.pipeline_version_id) - .findKebabAction('Create schedule') + .findKebabActionByMenuId('Create schedule', 'pipeline-actions') .click(); cy.url().should( @@ -1181,7 +1189,7 @@ describe('Pipelines', () => { pipelineRow.findExpandButton().click(); pipelineRow .getPipelineVersionRowById(initialMockPipelineVersion.pipeline_version_id) - .findKebabAction('View runs') + .findKebabActionByMenuId('View runs', 'pipeline-actions') .click(); cy.url().should( @@ -1199,7 +1207,7 @@ describe('Pipelines', () => { pipelineRow.findExpandButton().click(); pipelineRow .getPipelineVersionRowById(initialMockPipelineVersion.pipeline_version_id) - .findKebabAction('View schedules') + .findKebabActionByMenuId('View schedules', 'pipeline-version-actions') .click(); cy.url().should( diff --git a/frontend/src/__tests__/cypress/cypress/tests/mocked/pipelines/pipelinesList.cy.ts b/frontend/src/__tests__/cypress/cypress/tests/mocked/pipelines/pipelinesList.cy.ts index 49f247d976..0ad3ec99d6 100644 --- a/frontend/src/__tests__/cypress/cypress/tests/mocked/pipelines/pipelinesList.cy.ts +++ b/frontend/src/__tests__/cypress/cypress/tests/mocked/pipelines/pipelinesList.cy.ts @@ -148,7 +148,10 @@ describe('PipelinesList', () => { pipelinesTable.find(); const pipelineRow = pipelinesTable.getRowById(initialMockPipeline.pipeline_id); - pipelineRow.findKebabAction('Upload new version').should('be.visible').click(); + pipelineRow + .findKebabActionByMenuId('Upload new version', 'pipeline-actions') + .should('be.visible') + .click(); pipelineVersionImportModal.shouldBeOpen(); }); @@ -162,7 +165,7 @@ describe('PipelinesList', () => { pipelineRow .getPipelineVersionRowById(initialMockPipelineVersion.pipeline_version_id) .findPipelineVersionLink() - .click(); + .click({ force: true }); cy.url().should( 'include', @@ -196,7 +199,7 @@ describe('PipelinesList', () => { pipelinesTable.find(); pipelinesTable .getRowById(initialMockPipeline.pipeline_id) - .findKebabAction('Create run') + .findKebabActionByMenuId('Create run', 'pipeline-actions') .click(); cy.url().should( @@ -212,7 +215,7 @@ describe('PipelinesList', () => { pipelinesTable.find(); pipelinesTable .getRowById(initialMockPipeline.pipeline_id) - .findKebabAction('Create schedule') + .findKebabActionByMenuId('Create schedule', 'pipeline-actions') .click(); cy.url().should( diff --git a/frontend/src/__tests__/cypress/cypress/tests/mocked/projects/clusterStorage.cy.ts b/frontend/src/__tests__/cypress/cypress/tests/mocked/projects/clusterStorage.cy.ts index 33dddf5e95..d338f9f051 100644 --- a/frontend/src/__tests__/cypress/cypress/tests/mocked/projects/clusterStorage.cy.ts +++ b/frontend/src/__tests__/cypress/cypress/tests/mocked/projects/clusterStorage.cy.ts @@ -164,7 +164,7 @@ describe('ClusterStorage', () => { // select storage class addClusterStorageModal.findStorageClassSelect().click(); - addClusterStorageModal.find().findByText('Test SC 1').click(); + addClusterStorageModal.findStorageClassOption('Test SC 1').click(); addClusterStorageModal.findSubmitButton().should('be.enabled'); addClusterStorageModal.findDescriptionInput().fill('description'); addClusterStorageModal.findPVSizeMinusButton().click(); @@ -175,34 +175,34 @@ describe('ClusterStorage', () => { //connect workbench addClusterStorageModal.findWorkbenchConnectionSelect().click(); - addClusterStorageModal.find().findByText('Test Notebook').click(); + addClusterStorageModal.findWorkbenchConnectionOption('Test Notebook').click(); // don't allow duplicate path addClusterStorageModal.findMountField().clear(); addClusterStorageModal.findMountField().fill('test-dupe'); addClusterStorageModal .findMountFieldHelperText() - .should('have.text', 'Mount folder is already in use for this workbench.'); + .should('contain.text', 'Mount folder is already in use for this workbench.'); // don't allow number in the path addClusterStorageModal.findMountField().clear(); addClusterStorageModal.findMountField().fill('test2'); addClusterStorageModal .findMountFieldHelperText() - .should('have.text', 'Must only consist of lowercase letters and dashes.'); + .should('contain.text', 'Must only consist of lowercase letters and dashes.'); // Allow trailing slash addClusterStorageModal.findMountField().clear(); addClusterStorageModal.findMountField().fill('test/'); addClusterStorageModal .findMountFieldHelperText() - .should('have.text', 'Must consist of lowercase letters and dashes.'); + .should('contain.text', 'Must consist of lowercase letters and dashes.'); addClusterStorageModal.findMountField().clear(); addClusterStorageModal .findMountFieldHelperText() .should( - 'have.text', + 'contain.text', 'Enter a path to a model or folder. This path cannot point to a root folder.', ); addClusterStorageModal.findMountField().fill('data'); @@ -275,11 +275,11 @@ describe('ClusterStorage', () => { clusterStorage.visit('test-project'); const clusterStorageRow = clusterStorage.getClusterStorageRow('Existing PVC'); - clusterStorageRow.findKebabAction('Edit storage').click(); + clusterStorageRow.findKebabActionByMenuId('Edit storage', 'cluster-storage-actions').click(); // Connect to 'Another Notebook' updateClusterStorageModal.findWorkbenchConnectionSelect().click(); - updateClusterStorageModal.find().findByText('Another Notebook').click(); + updateClusterStorageModal.findWorkbenchConnectionOption('Another Notebook').click(); updateClusterStorageModal.findMountField().fill('new-data'); @@ -338,7 +338,7 @@ describe('ClusterStorage', () => { initInterceptors({}); clusterStorage.visit('test-project'); const clusterStorageRow = clusterStorage.getClusterStorageRow('Test Storage'); - clusterStorageRow.findKebabAction('Edit storage').click(); + clusterStorageRow.findKebabActionByMenuId('Edit storage', 'cluster-storage-actions').click(); updateClusterStorageModal.findNameInput().should('have.value', 'Test Storage'); updateClusterStorageModal.findPVSizeInput().should('have.value', '5'); updateClusterStorageModal.shouldHavePVSizeSelectValue('GiB'); @@ -380,7 +380,7 @@ describe('ClusterStorage', () => { initInterceptors({}); clusterStorage.visit('test-project'); const clusterStorageRow = clusterStorage.getClusterStorageRow('Unbound storage'); - clusterStorageRow.findKebabAction('Edit storage').click(); + clusterStorageRow.findKebabActionByMenuId('Edit storage', 'cluster-storage-actions').click(); updateClusterStorageModal.findNameInput().should('have.value', 'Unbound storage'); updateClusterStorageModal.findPVSizeInput().should('have.value', '5').should('be.disabled'); updateClusterStorageModal.shouldHavePVSizeSelectValue('GiB').should('be.disabled'); @@ -391,7 +391,7 @@ describe('ClusterStorage', () => { initInterceptors({}); clusterStorage.visit('test-project'); const clusterStorageRow = clusterStorage.getClusterStorageRow('Test Storage'); - clusterStorageRow.findKebabAction('Delete storage').click(); + clusterStorageRow.findKebabActionByMenuId('Delete storage', 'cluster-storage-actions').click(); deleteModal.findInput().fill('Test Storage'); cy.interceptK8s( diff --git a/frontend/src/__tests__/cypress/cypress/tests/mocked/projects/dataConnection.cy.ts b/frontend/src/__tests__/cypress/cypress/tests/mocked/projects/dataConnection.cy.ts index 16e89b3649..21bddb0d5c 100644 --- a/frontend/src/__tests__/cypress/cypress/tests/mocked/projects/dataConnection.cy.ts +++ b/frontend/src/__tests__/cypress/cypress/tests/mocked/projects/dataConnection.cy.ts @@ -157,7 +157,9 @@ describe('Data connections', () => { projectDetails.shouldBeEmptyState('Data connections', 'data-connections', false); const dataConnectionRow = projectDetails.getDataConnectionRow('Test Secret'); dataConnectionRow.findWorkbenchConnection().contains('No connections'); - dataConnectionRow.findKebabAction('Edit data connection').click(); + dataConnectionRow + .findKebabActionByMenuId('Edit data connection', 'data-connection-actions') + .click(); editDataConnectionModal.findNameInput().should('have.value', 'Test Secret'); editDataConnectionModal.findAwsKeyInput().should('have.value', 'sdsd'); @@ -211,7 +213,9 @@ describe('Data connections', () => { initIntercepts({}); projectDetails.visitSection('test-project', 'data-connections'); const dataConnectionRow = projectDetails.getDataConnectionRow('Test Secret'); - dataConnectionRow.findKebabAction('Delete data connection').click(); + dataConnectionRow + .findKebabActionByMenuId('Delete data connection', 'data-connection-actions') + .click(); deleteModal.findInput().type('Test Secret'); cy.interceptK8s( 'DELETE', diff --git a/frontend/src/__tests__/cypress/cypress/tests/mocked/projects/permissions.cy.ts b/frontend/src/__tests__/cypress/cypress/tests/mocked/projects/permissions.cy.ts index 9276fe502a..a2a794e95b 100644 --- a/frontend/src/__tests__/cypress/cypress/tests/mocked/projects/permissions.cy.ts +++ b/frontend/src/__tests__/cypress/cypress/tests/mocked/projects/permissions.cy.ts @@ -138,7 +138,10 @@ describe('Permissions tab', () => { permissions.visit('test-project'); - userTable.getTableRow('user-1').findKebabAction('Edit').click(); + userTable + .getTableRow('user-1') + .findKebabActionByMenuId('Edit', 'role-bindings-permissions-actions') + .click(); userTable.findEditInput('user-1').clear().type('user-3'); userTable.selectPermission('user-3', 'Admin Edit the project and manage user access'); userTable.findEditSaveButton('user-3').click(); @@ -168,7 +171,10 @@ describe('Permissions tab', () => { ).as('deleteUser'); permissions.visit('test-project'); - userTable.getTableRow('user-1').findKebabAction('Delete').click(); + userTable + .getTableRow('user-1') + .findKebabActionByMenuId('Delete', 'role-bindings-permissions-actions') + .click(); cy.wait('@deleteUser'); }); @@ -232,7 +238,10 @@ describe('Permissions tab', () => { permissions.visit('test-project'); - groupTable.getTableRow('group-1').findKebabAction('Edit').click(); + groupTable + .getTableRow('group-1') + .findKebabActionByMenuId('Edit', 'role-bindings-permissions-actions') + .click(); groupTable.findEditInput('group-1').clear().type('group-3'); groupTable.selectPermission('group-3', 'Admin Edit the project and manage user access'); groupTable.findEditSaveButton('group-3').click(); @@ -262,7 +271,10 @@ describe('Permissions tab', () => { ).as('deleteGroup'); permissions.visit('test-project'); - groupTable.getTableRow('group-1').findKebabAction('Delete').click(); + groupTable + .getTableRow('group-1') + .findKebabActionByMenuId('Delete', 'role-bindings-permissions-actions') + .click(); cy.wait('@deleteGroup'); }); diff --git a/frontend/src/__tests__/cypress/cypress/tests/mocked/projects/projectList.cy.ts b/frontend/src/__tests__/cypress/cypress/tests/mocked/projects/projectList.cy.ts index 7a47a30687..4fcd406708 100644 --- a/frontend/src/__tests__/cypress/cypress/tests/mocked/projects/projectList.cy.ts +++ b/frontend/src/__tests__/cypress/cypress/tests/mocked/projects/projectList.cy.ts @@ -107,13 +107,16 @@ describe('Data science projects details', () => { ).as('selfSubjectAccessReviewsCall'); const deleteProject = projectListPage .getProjectRow('Test Project') - .findKebabAction('Delete project'); + .findKebabActionByMenuId('Delete project', 'project-actions'); cy.wait('@selfSubjectAccessReviewsCall'); deleteProject.click(); deleteModal.shouldBeOpen(); deleteModal.findSubmitButton().should('be.disabled'); deleteModal.findCancelButton().should('be.enabled').click(); - projectListPage.getProjectRow('Test Project').findKebabAction('Delete project').click(); + projectListPage + .getProjectRow('Test Project') + .findKebabActionByMenuId('Delete project', 'project-actions') + .click(); deleteModal.findInput().type('Test Project'); cy.interceptK8s( @@ -196,13 +199,13 @@ describe('Data science projects details', () => { const editProject = projectListPage .getProjectRow('Test Project') - .findKebabAction('Edit project'); + .findKebabActionByMenuId('Edit project', 'project-actions'); const editPermission = projectListPage .getProjectRow('Test Project') - .findKebabAction('Edit permissions'); + .findKebabActionByMenuId('Edit permissions', 'project-actions'); const deleteProject = projectListPage .getProjectRow('Test Project') - .findKebabAction('Delete project'); + .findKebabActionByMenuId('Delete project', 'project-actions'); cy.wait('@selfSubjectAccessReviewsCall'); editProject.should('have.attr', 'aria-disabled', 'true'); diff --git a/frontend/src/__tests__/cypress/cypress/tests/mocked/projects/workbench.cy.ts b/frontend/src/__tests__/cypress/cypress/tests/mocked/projects/workbench.cy.ts index fa92fcba22..d2fdbfddcd 100644 --- a/frontend/src/__tests__/cypress/cypress/tests/mocked/projects/workbench.cy.ts +++ b/frontend/src/__tests__/cypress/cypress/tests/mocked/projects/workbench.cy.ts @@ -905,7 +905,7 @@ describe('Workbench page', () => { const notebookRow = workbenchPage.getNotebookRow('Test Notebook'); notebookRow.shouldHaveNotebookImageName('Test Image'); notebookRow.shouldHaveContainerSize('Custom'); - notebookRow.findKebabAction('Edit workbench').click(); + notebookRow.findKebabActionByMenuId('Edit workbench', 'notebook-actions').click(); editSpawnerPage.shouldHaveContainerSizeInput('Keep custom size'); cy.go('back'); workbenchPage.findCreateButton().click(); @@ -972,7 +972,7 @@ describe('Workbench page', () => { ); workbenchPage.visit('test-project'); const notebookRow = workbenchPage.getNotebookRow('Test Notebook'); - notebookRow.findKebabAction('Delete workbench').click(); + notebookRow.findKebabActionByMenuId('Delete workbench', 'notebook-actions').click(); deleteModal.findInput().fill('Test Notebook'); cy.interceptK8s( 'DELETE', diff --git a/frontend/src/__tests__/cypress/cypress/tests/mocked/storageClasses/storageClasses.cy.ts b/frontend/src/__tests__/cypress/cypress/tests/mocked/storageClasses/storageClasses.cy.ts index 4e68eb052f..1120c3f149 100644 --- a/frontend/src/__tests__/cypress/cypress/tests/mocked/storageClasses/storageClasses.cy.ts +++ b/frontend/src/__tests__/cypress/cypress/tests/mocked/storageClasses/storageClasses.cy.ts @@ -114,12 +114,15 @@ describe('Storage classes', () => { storageClassesTable .getRowByConfigName('openshift-default-sc') - .findKebabAction('Edit') + .findKebabActionByMenuId('Edit', 'storage-class-actions') .click(); storageClassEditModal.findOpenshiftDefaultLabel().should('be.visible'); storageClassEditModal.findCloseButton().click(); - storageClassesTable.getRowByConfigName('Test SC 1').findKebabAction('Edit').click(); + storageClassesTable + .getRowByConfigName('Test SC 1') + .findKebabActionByMenuId('Edit', 'storage-class-actions') + .click(); storageClassEditModal.findOpenshiftScName().should('have.text', 'test-storage-class-1'); storageClassEditModal.findProvisioner().should('have.text', 'manila.csi.openstack.org'); storageClassEditModal.findOpenshiftDefaultLabel().should('not.exist'); @@ -162,7 +165,7 @@ describe('Storage classes', () => { storageClassTableRow.findLastModifiedValue().should('have.text', '-'); storageClassTableRow.findEnableValue().should('have.text', '-'); storageClassTableRow.find().findByTestId('corrupted-metadata-alert').should('be.visible'); - storageClassTableRow.findKebabAction('Edit').click(); + storageClassTableRow.findKebabActionByMenuId('Edit', 'storage-class-actions').click(); storageClassEditModal.findInfoAlert().should('contain.text', 'Reset the metadata'); storageClassEditModal.fillDisplayNameInput('Readable config'); diff --git a/frontend/src/app/AppLauncher.tsx b/frontend/src/app/AppLauncher.tsx index 4d0d6c3fe7..86b5c57c9c 100644 --- a/frontend/src/app/AppLauncher.tsx +++ b/frontend/src/app/AppLauncher.tsx @@ -150,7 +150,7 @@ const AppLauncher: React.FC = () => { return ( setIsOpen(isOpenChange)} onSelect={onSelect} toggle={(toggleRef) => ( diff --git a/frontend/src/components/EmptyDetailsView.tsx b/frontend/src/components/EmptyDetailsView.tsx index 9e6be13444..cb93e92ff6 100644 --- a/frontend/src/components/EmptyDetailsView.tsx +++ b/frontend/src/components/EmptyDetailsView.tsx @@ -28,6 +28,7 @@ const EmptyDetailsView: React.FC = ({ imageSize = '320px', }) => ( ({ )} isOpen={open} + popperProps={{ appendTo: 'inline' }} > {keys.map((filterKey) => ( diff --git a/frontend/src/components/MultiSelection.tsx b/frontend/src/components/MultiSelection.tsx index d3a2139187..c2096b5322 100644 --- a/frontend/src/components/MultiSelection.tsx +++ b/frontend/src/components/MultiSelection.tsx @@ -20,6 +20,7 @@ import { SelectGroup, Divider, SelectOptionProps, + SelectPopperProps, } from '@patternfly/react-core'; import { TimesIcon } from '@patternfly/react-icons/dist/esm/icons/times-icon'; @@ -56,6 +57,7 @@ type MultiSelectionProps = { /** Message to display to create a new option */ createOptionMessage?: string | ((newValue: string) => string); filterFunction?: (filterText: string, options: SelectionOptions[]) => SelectionOptions[]; + popperProps?: SelectPopperProps; }; const defaultCreateOptionMessage = (newValue: string) => `Create "${newValue}"`; @@ -79,6 +81,7 @@ export const MultiSelection: React.FC = ({ isCreateOptionOnTop = false, createOptionMessage = defaultCreateOptionMessage, filterFunction = defaultFilterFunction, + popperProps, }) => { const [isOpen, setIsOpen] = React.useState(false); const [inputValue, setInputValue] = React.useState(''); @@ -324,6 +327,7 @@ export const MultiSelection: React.FC = ({ }} onOpenChange={() => setOpen(false)} toggle={toggle} + popperProps={popperProps} > {createOption && isCreateOptionOnTop && groupOptions.length > 0 ? ( diff --git a/frontend/src/components/SimpleMenuActions.tsx b/frontend/src/components/SimpleMenuActions.tsx index 5ee280cdf6..abf0ed914f 100644 --- a/frontend/src/components/SimpleMenuActions.tsx +++ b/frontend/src/components/SimpleMenuActions.tsx @@ -61,7 +61,9 @@ const SimpleMenuActions: React.FC = ({ {toggleLabel ?? } )} - popperProps={!toggleLabel ? { position: 'right' } : undefined} + popperProps={ + !toggleLabel ? { position: 'right', appendTo: 'inline' } : { appendTo: 'inline' } + } > {dropdownItems.map((itemOrSpacer, i) => diff --git a/frontend/src/components/searchSelector/SearchSelector.tsx b/frontend/src/components/searchSelector/SearchSelector.tsx index 0dd313ab61..8629c61222 100644 --- a/frontend/src/components/searchSelector/SearchSelector.tsx +++ b/frontend/src/components/searchSelector/SearchSelector.tsx @@ -63,12 +63,13 @@ const SearchSelector: React.FC = ({ const toggleRef = React.useRef(null); const menuRef = React.useRef(null); const searchRef = React.useRef(null); + const popperProps = { minWidth, maxWidth: 'trigger', appendTo: 'inline' }; return ( { setIsOpen(open); onSearchClear(); diff --git a/frontend/src/components/table/TableBase.tsx b/frontend/src/components/table/TableBase.tsx index 937f50a62c..98e4483d17 100644 --- a/frontend/src/components/table/TableBase.tsx +++ b/frontend/src/components/table/TableBase.tsx @@ -138,6 +138,7 @@ const TableBase = ({ variant={variant} widgetId="table-pagination" perPageOptions={perPageOptions} + menuAppendTo="inline" titles={{ paginationAriaLabel: `${variant} pagination`, }} diff --git a/frontend/src/concepts/dashboard/DashboardSearchField.tsx b/frontend/src/concepts/dashboard/DashboardSearchField.tsx index fc0f63a7d2..718ffe6309 100644 --- a/frontend/src/concepts/dashboard/DashboardSearchField.tsx +++ b/frontend/src/concepts/dashboard/DashboardSearchField.tsx @@ -57,6 +57,7 @@ const DashboardSearchField: React.FC = ({ } }} icon={icon} + popperProps={{ appendTo: 'inline' }} /> diff --git a/frontend/src/concepts/metrics/kserve/KserveMetricsContext.tsx b/frontend/src/concepts/metrics/kserve/KserveMetricsContext.tsx index 04859061f9..70f3cf9c86 100644 --- a/frontend/src/concepts/metrics/kserve/KserveMetricsContext.tsx +++ b/frontend/src/concepts/metrics/kserve/KserveMetricsContext.tsx @@ -79,6 +79,7 @@ export const KserveMetricsContextProvider = conditionalArea + {modelName} is using a custom serving runtime. Metrics are only supported for models served via a pre-installed runtime when the single-model serving platform is enabled for a diff --git a/frontend/src/concepts/pipelines/content/createRun/contentSections/TriggerTypeField.tsx b/frontend/src/concepts/pipelines/content/createRun/contentSections/TriggerTypeField.tsx index 0707eb258c..af425c2b15 100644 --- a/frontend/src/concepts/pipelines/content/createRun/contentSections/TriggerTypeField.tsx +++ b/frontend/src/concepts/pipelines/content/createRun/contentSections/TriggerTypeField.tsx @@ -117,6 +117,7 @@ const TriggerTypeField: React.FC = ({ data, onChange }) = onChange({ ...data, triggerType, value }); }} + popperProps={{ appendTo: 'inline' }} /> diff --git a/frontend/src/concepts/pipelines/content/import/ImportPipelineSplitButton.tsx b/frontend/src/concepts/pipelines/content/import/ImportPipelineSplitButton.tsx index 870db82137..48cfd09316 100644 --- a/frontend/src/concepts/pipelines/content/import/ImportPipelineSplitButton.tsx +++ b/frontend/src/concepts/pipelines/content/import/ImportPipelineSplitButton.tsx @@ -63,6 +63,7 @@ const ImportPipelineSplitButton: React.FC = ({ data-testid="import-pipeline-split-button" /> )} + popperProps={{ appendTo: 'inline' }} > {disableUploadVersion && ( diff --git a/frontend/src/concepts/pipelines/content/pipelinesDetails/pipelineRun/runLogs/LogsTab.tsx b/frontend/src/concepts/pipelines/content/pipelinesDetails/pipelineRun/runLogs/LogsTab.tsx index e5ccbaa959..a0a1240f0e 100644 --- a/frontend/src/concepts/pipelines/content/pipelinesDetails/pipelineRun/runLogs/LogsTab.tsx +++ b/frontend/src/concepts/pipelines/content/pipelinesDetails/pipelineRun/runLogs/LogsTab.tsx @@ -266,6 +266,7 @@ const LogsTab: React.FC = ({ task, isCached }) => { )} shouldFocusToggleOnSelect + popperProps={{ appendTo: 'inline' }} > {defaultContainerName && ( <> diff --git a/frontend/src/concepts/pipelines/content/tables/experiment/ExperimentTableRow.tsx b/frontend/src/concepts/pipelines/content/tables/experiment/ExperimentTableRow.tsx index e5e4b762c0..6c4390bd52 100644 --- a/frontend/src/concepts/pipelines/content/tables/experiment/ExperimentTableRow.tsx +++ b/frontend/src/concepts/pipelines/content/tables/experiment/ExperimentTableRow.tsx @@ -58,7 +58,7 @@ const ExperimentTableRow: React.FC = ({ - + ); diff --git a/frontend/src/concepts/pipelines/content/tables/pipeline/PipelinesTableRow.tsx b/frontend/src/concepts/pipelines/content/tables/pipeline/PipelinesTableRow.tsx index cdc7dc0d7c..eafba2abd4 100644 --- a/frontend/src/concepts/pipelines/content/tables/pipeline/PipelinesTableRow.tsx +++ b/frontend/src/concepts/pipelines/content/tables/pipeline/PipelinesTableRow.tsx @@ -121,6 +121,7 @@ const PipelinesTableRow: React.FC = ({ {loading ? : } = ({ {hasRowActions && ( = }))} onChange={(v) => onChange(v)} dataTestId="runtime-status-dropdown" - popperProps={{ maxWidth: undefined }} + popperProps={{ maxWidth: undefined, appendTo: 'inline' }} /> ), }} diff --git a/frontend/src/concepts/pipelines/content/tables/pipelineVersion/PipelineVersionTableRow.tsx b/frontend/src/concepts/pipelines/content/tables/pipelineVersion/PipelineVersionTableRow.tsx index 5f989029b8..55be1ca7cf 100644 --- a/frontend/src/concepts/pipelines/content/tables/pipelineVersion/PipelineVersionTableRow.tsx +++ b/frontend/src/concepts/pipelines/content/tables/pipelineVersion/PipelineVersionTableRow.tsx @@ -72,6 +72,7 @@ const PipelineVersionTableRow: React.FC = ({ ) : ( = ({ = ( = ({ toleration, onEdit, onDel {formatSeconds(toleration.tolerationSeconds)} = ({ = ({ { setValue={(newState) => handleMenuItemSelection(newState, GroupsConfigField.ADMIN)} selectionRequired noSelectedOptionsMessage="One or more group must be selected" + popperProps={{ appendTo: 'inline' }} /> {groupSettings.errorAdmin ? ( { setValue={(newState) => handleMenuItemSelection(newState, GroupsConfigField.USER)} selectionRequired noSelectedOptionsMessage="One or more group must be selected" + popperProps={{ appendTo: 'inline' }} /> {groupSettings.errorUser ? ( = React.memo if (filteredDocApps.length === 0) { return ( = ({ ) } onChange={onSortOrderSelect} + popperProps={{ appendTo: 'inline' }} /> diff --git a/frontend/src/pages/modelRegistry/screens/ModelPropertiesTableRow.tsx b/frontend/src/pages/modelRegistry/screens/ModelPropertiesTableRow.tsx index bacd81cc82..c67fcf26e4 100644 --- a/frontend/src/pages/modelRegistry/screens/ModelPropertiesTableRow.tsx +++ b/frontend/src/pages/modelRegistry/screens/ModelPropertiesTableRow.tsx @@ -175,6 +175,7 @@ const ModelPropertiesTableRow: React.FC = ({ ) : ( setOpenActionDropdown(false)} onOpenChange={(open) => setOpenActionDropdown(open)} - popperProps={{ position: 'right' }} + popperProps={{ position: 'right', appendTo: 'inline' }} toggle={(toggleRef) => ( = ({ )} shouldFocusToggleOnSelect + popperProps={{ appendTo: 'inline' }} > = ({ isOpen={isOpen} onSelect={() => setOpen(false)} onOpenChange={(open) => setOpen(open)} - popperProps={{ position: 'end' }} + popperProps={{ position: 'end', appendTo: 'inline' }} toggle={(toggleRef) => ( = ({ {!isArchiveModel && ( - + {isArchiveModalOpen ? ( setIsArchiveModalOpen(false)} diff --git a/frontend/src/pages/modelRegistry/screens/RegisterModel/ConnectionDropdown.tsx b/frontend/src/pages/modelRegistry/screens/RegisterModel/ConnectionDropdown.tsx index 4828524782..b50b6dc1eb 100644 --- a/frontend/src/pages/modelRegistry/screens/RegisterModel/ConnectionDropdown.tsx +++ b/frontend/src/pages/modelRegistry/screens/RegisterModel/ConnectionDropdown.tsx @@ -84,6 +84,7 @@ export const ConnectionDropdown = ({ )} isOpen={isOpen} + popperProps={{ appendTo: 'inline' }} > diff --git a/frontend/src/pages/modelRegistry/screens/RegisteredModels/RegisteredModelTableRow.tsx b/frontend/src/pages/modelRegistry/screens/RegisteredModels/RegisteredModelTableRow.tsx index a3102ee64e..1b9fd117ac 100644 --- a/frontend/src/pages/modelRegistry/screens/RegisteredModels/RegisteredModelTableRow.tsx +++ b/frontend/src/pages/modelRegistry/screens/RegisteredModels/RegisteredModelTableRow.tsx @@ -105,7 +105,7 @@ const RegisteredModelTableRow: React.FC = ({ - + {isArchiveModalOpen ? ( setIsArchiveModalOpen(false)} diff --git a/frontend/src/pages/modelRegistrySettings/ModelRegistriesTableRow.tsx b/frontend/src/pages/modelRegistrySettings/ModelRegistriesTableRow.tsx index f09e2ec50a..9d689b078b 100644 --- a/frontend/src/pages/modelRegistrySettings/ModelRegistriesTableRow.tsx +++ b/frontend/src/pages/modelRegistrySettings/ModelRegistriesTableRow.tsx @@ -63,6 +63,7 @@ const ModelRegistriesTableRow: React.FC = ({ = ({ = ({ model }) => { = ({ } }} isDisabled={projectConnections.length === 0} + popperProps={{ appendTo: 'inline' }} /> {selectedConnection && ( = ( dataConnection: option, }); }} + popperProps={{ appendTo: 'inline' }} /> diff --git a/frontend/src/pages/modelServing/screens/projects/InferenceServiceModal/InferenceServiceFrameworkSection.tsx b/frontend/src/pages/modelServing/screens/projects/InferenceServiceModal/InferenceServiceFrameworkSection.tsx index df876f84d0..5e79bb231d 100644 --- a/frontend/src/pages/modelServing/screens/projects/InferenceServiceModal/InferenceServiceFrameworkSection.tsx +++ b/frontend/src/pages/modelServing/screens/projects/InferenceServiceModal/InferenceServiceFrameworkSection.tsx @@ -74,6 +74,7 @@ const InferenceServiceFrameworkSection: React.FC {registeredModelFormat && models.length !== 0 && ( diff --git a/frontend/src/pages/modelServing/screens/projects/InferenceServiceModal/InferenceServiceServingRuntimeSection.tsx b/frontend/src/pages/modelServing/screens/projects/InferenceServiceModal/InferenceServiceServingRuntimeSection.tsx index 85e82c7e79..7384a6e7ee 100644 --- a/frontend/src/pages/modelServing/screens/projects/InferenceServiceModal/InferenceServiceServingRuntimeSection.tsx +++ b/frontend/src/pages/modelServing/screens/projects/InferenceServiceModal/InferenceServiceServingRuntimeSection.tsx @@ -68,6 +68,7 @@ const InferenceServiceServingRuntimeSection: React.FC< }); } }} + popperProps={{ appendTo: 'inline' }} /> ); diff --git a/frontend/src/pages/modelServing/screens/projects/InferenceServiceModal/ProjectSelector.tsx b/frontend/src/pages/modelServing/screens/projects/InferenceServiceModal/ProjectSelector.tsx index b61b2ac037..0e432aebe0 100644 --- a/frontend/src/pages/modelServing/screens/projects/InferenceServiceModal/ProjectSelector.tsx +++ b/frontend/src/pages/modelServing/screens/projects/InferenceServiceModal/ProjectSelector.tsx @@ -62,6 +62,7 @@ const ProjectSelector: React.FC = ({ : 'Select target project' } toggleProps={{ id: 'deploy-model-project-selector' }} + popperProps={{ appendTo: 'inline' }} /> {error && selectedProject && ( diff --git a/frontend/src/pages/modelServing/screens/projects/ModelMeshSection/ServingRuntimeTableRow.tsx b/frontend/src/pages/modelServing/screens/projects/ModelMeshSection/ServingRuntimeTableRow.tsx index 54ba23d406..d27f00ddc2 100644 --- a/frontend/src/pages/modelServing/screens/projects/ModelMeshSection/ServingRuntimeTableRow.tsx +++ b/frontend/src/pages/modelServing/screens/projects/ModelMeshSection/ServingRuntimeTableRow.tsx @@ -190,6 +190,7 @@ const ServingRuntimeTableRow: React.FC = ({ {data.servingRuntimeTemplateName && onConfigureParamsClick && ( diff --git a/frontend/src/pages/notebookController/screens/admin/NotebookActions.tsx b/frontend/src/pages/notebookController/screens/admin/NotebookActions.tsx index 6e26a7d4ff..ec24d6b99a 100644 --- a/frontend/src/pages/notebookController/screens/admin/NotebookActions.tsx +++ b/frontend/src/pages/notebookController/screens/admin/NotebookActions.tsx @@ -23,7 +23,7 @@ const NotebookActions: React.FC = ({ data }) => { }, ]; - return ; + return ; }; export default NotebookActions; diff --git a/frontend/src/pages/projects/notebook/ConnectedNotebookField.tsx b/frontend/src/pages/projects/notebook/ConnectedNotebookField.tsx index d6deacffac..19e6024fdb 100644 --- a/frontend/src/pages/projects/notebook/ConnectedNotebookField.tsx +++ b/frontend/src/pages/projects/notebook/ConnectedNotebookField.tsx @@ -56,6 +56,7 @@ const ConnectedNotebookField: React.FC = ({ > {isMultiSelect ? ( ({ @@ -69,6 +70,7 @@ const ConnectedNotebookField: React.FC = ({ /> ) : ( = ({ return ( = ({ = ({ /> - + diff --git a/frontend/src/pages/projects/screens/projects/EmptyProjects.tsx b/frontend/src/pages/projects/screens/projects/EmptyProjects.tsx index 12ef29e9b7..7ea357321e 100644 --- a/frontend/src/pages/projects/screens/projects/EmptyProjects.tsx +++ b/frontend/src/pages/projects/screens/projects/EmptyProjects.tsx @@ -14,6 +14,7 @@ const EmptyProjects: React.FC = ({ allowCreate }) => { return ( no projects} titleText={allowCreate ? 'Start by creating your project' : 'Start by requesting a project'} diff --git a/frontend/src/pages/projects/screens/projects/ProjectTableRow.tsx b/frontend/src/pages/projects/screens/projects/ProjectTableRow.tsx index f275255cbe..4ce3a988a2 100644 --- a/frontend/src/pages/projects/screens/projects/ProjectTableRow.tsx +++ b/frontend/src/pages/projects/screens/projects/ProjectTableRow.tsx @@ -99,7 +99,8 @@ const ProjectTableRow: React.FC = ({ ? { isExpanded: expandColumn === ExpandableColumns.WORKBENCHES, columnIndex: ExpandableColumns.WORKBENCHES, - expandId: `expand-table-row-${project.metadata.name}-workbenches`, + rowIndex: 1, + expandId: `expand-table-row`, onToggle: (_, __, column) => toggleExpandColumn(column), } : undefined @@ -123,7 +124,7 @@ const ProjectTableRow: React.FC = ({ onMouseEnter={runAccessCheck} onClick={runAccessCheck} > - + {expandColumn ? ( diff --git a/frontend/src/pages/projects/screens/spawner/EditSpawnerPage.tsx b/frontend/src/pages/projects/screens/spawner/EditSpawnerPage.tsx index 65b1bae0d9..e6cb38e681 100644 --- a/frontend/src/pages/projects/screens/spawner/EditSpawnerPage.tsx +++ b/frontend/src/pages/projects/screens/spawner/EditSpawnerPage.tsx @@ -60,6 +60,7 @@ const EditSpawnerPage: React.FC = () => { return ( = ({ {envVarConflicts.length > 0 && } { expect(within(attachModal).getByRole('combobox', { name: 'Type to filter' })).toHaveValue(''); await act(async () => result.getByRole('button', { name: 'Connections' }).click()); - expect(within(attachModal).queryByRole('option', { name: 's3 connection 1' })).toBeFalsy(); // don't show attached connections - expect(within(attachModal).getByRole('option', { name: 's3 connection 2' })).toBeTruthy(); - expect(within(attachModal).getByRole('option', { name: 's3 connection 3' })).toBeTruthy(); + expect(result.queryByRole('option', { name: 's3 connection 1' })).toBeFalsy(); // don't show attached connections + expect(result.getByRole('option', { name: 's3 connection 2' })).toBeTruthy(); + expect(result.getByRole('option', { name: 's3 connection 3' })).toBeTruthy(); await act(async () => result.getByRole('option', { name: 's3 connection 3' }).click()); - expect( - within(attachModal).getByRole('group', { name: 'Current selections' }), - ).toHaveTextContent('s3 connection 3'); + expect(result.getByRole('list', { name: 'Current selections' })).toHaveTextContent( + 's3 connection 3', + ); await act(async () => result.getByRole('button', { name: 'Attach' }).click()); expect(result.queryByRole('dialog', { name: 'Attach existing connections' })).toBeFalsy(); diff --git a/frontend/src/pages/projects/screens/spawner/dataConnection/ExistingDataConnectionField.tsx b/frontend/src/pages/projects/screens/spawner/dataConnection/ExistingDataConnectionField.tsx index 183264cdca..bd932e9478 100644 --- a/frontend/src/pages/projects/screens/spawner/dataConnection/ExistingDataConnectionField.tsx +++ b/frontend/src/pages/projects/screens/spawner/dataConnection/ExistingDataConnectionField.tsx @@ -56,6 +56,7 @@ const ExistingDataConnectionField: React.FC = data-testid="data-connection-group" > setDataConnection(String(selection))} diff --git a/frontend/src/pages/projects/screens/spawner/imageSelector/ImageStreamSelector.tsx b/frontend/src/pages/projects/screens/spawner/imageSelector/ImageStreamSelector.tsx index ea7ca50eba..514aa717f7 100644 --- a/frontend/src/pages/projects/screens/spawner/imageSelector/ImageStreamSelector.tsx +++ b/frontend/src/pages/projects/screens/spawner/imageSelector/ImageStreamSelector.tsx @@ -60,6 +60,7 @@ const ImageStreamSelector: React.FC = ({ options={options} placeholder="Select one" value={selectedImageStream?.metadata.name ?? ''} + popperProps={{ appendTo: 'inline' }} onChange={(key) => { const imageStream = imageStreams.find( (currentImageStream) => currentImageStream.metadata.name === key, diff --git a/frontend/src/pages/projects/screens/spawner/imageSelector/ImageVersionSelector.tsx b/frontend/src/pages/projects/screens/spawner/imageSelector/ImageVersionSelector.tsx index 552941adff..98175e2b49 100644 --- a/frontend/src/pages/projects/screens/spawner/imageSelector/ImageVersionSelector.tsx +++ b/frontend/src/pages/projects/screens/spawner/imageSelector/ImageVersionSelector.tsx @@ -85,6 +85,7 @@ const ImageVersionSelector: React.FC = ({ } toggleLabel={selectedImageVersion?.name ?? 'Select one'} aria-label="Image version select" + popperProps={{ appendTo: 'inline' }} /> {isSelectedImageVersionOutOfDate && ( diff --git a/frontend/src/pages/projects/screens/spawner/storage/CreateNewStorageSection.tsx b/frontend/src/pages/projects/screens/spawner/storage/CreateNewStorageSection.tsx index 79a461354d..9bfbede5b1 100644 --- a/frontend/src/pages/projects/screens/spawner/storage/CreateNewStorageSection.tsx +++ b/frontend/src/pages/projects/screens/spawner/storage/CreateNewStorageSection.tsx @@ -13,7 +13,7 @@ type CreateNewStorageSectionProps = { setData: UpdateObjectAtPropAndValue; currentStatus?: PersistentVolumeClaimKind['status']; autoFocusName?: boolean; - menuAppendTo?: HTMLElement; + menuAppendTo?: HTMLElement | 'inline'; disableStorageClassSelect?: boolean; onNameChange?: (value: string) => void; hasDuplicateName?: boolean; @@ -62,7 +62,6 @@ const CreateNewStorageSection = ({ void; disableStorageClassSelect?: boolean; - menuAppendTo?: HTMLElement; + menuAppendTo?: HTMLElement | 'inline'; }; const StorageClassSelect: React.FC = ({ @@ -34,7 +34,7 @@ const StorageClassSelect: React.FC = ({ const [defaultSc] = useDefaultStorageClass(); const enabledStorageClasses = storageClasses - .filter((sc) => getStorageClassConfig(sc)?.isEnabled === true) + // .filter((sc) => getStorageClassConfig(sc)?.isEnabled === true) .toSorted((a, b) => { const aConfig = getStorageClassConfig(a); const bConfig = getStorageClassConfig(b); @@ -75,7 +75,7 @@ const StorageClassSelect: React.FC = ({ {config?.displayName || sc.metadata.name} - {/* If multiple storage classes have `isDefault` set to true, + {/* If multiple storage classes have `isDefault` set to true, prioritize the one returned by useDefaultStorageClass() as the default class */} {sc.metadata.name === defaultSc?.metadata.name && (