Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Keep up with midstream #706

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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions clients/ui/frontend/.env
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ LOGO_DARK=logo-dark-theme.svg
FAVICON=favicon.ico
PRODUCT_NAME="Model Registry"
STYLE_THEME=mui-theme
PLATFORM_MODE=kubeflow

2 changes: 1 addition & 1 deletion clients/ui/frontend/src/__mocks__/mockModelRegistry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ type MockModelRegistry = {

export const mockModelRegistry = ({
name = 'modelregistry-sample',
description = 'New model registry',
description = 'Model registry description',
displayName = 'Model Registry Sample',
}: MockModelRegistry): ModelRegistry => ({
name,
Expand Down
9 changes: 4 additions & 5 deletions clients/ui/frontend/src/__mocks__/mockModelVersion.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,22 @@
import { ModelVersion, ModelState } from '~/app/types';
import { createModelRegistryLabelsObject } from './utils';
import { ModelVersion, ModelState, ModelRegistryCustomProperties } from '~/app/types';

type MockModelVersionType = {
author?: string;
id?: string;
registeredModelId?: string;
name?: string;
labels?: string[];
state?: ModelState;
description?: string;
createTimeSinceEpoch?: string;
lastUpdateTimeSinceEpoch?: string;
customProperties?: ModelRegistryCustomProperties;
};

export const mockModelVersion = ({
author = 'Test author',
registeredModelId = '1',
name = 'new model version',
labels = [],
customProperties = {},
id = '1',
state = ModelState.LIVE,
description = 'Description of model version',
Expand All @@ -26,7 +25,7 @@ export const mockModelVersion = ({
}: MockModelVersionType): ModelVersion => ({
author,
createTimeSinceEpoch,
customProperties: createModelRegistryLabelsObject(labels),
customProperties,
id,
lastUpdateTimeSinceEpoch,
name,
Expand Down
9 changes: 4 additions & 5 deletions clients/ui/frontend/src/__mocks__/mockRegisteredModel.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
import { ModelState, RegisteredModel } from '~/app/types';
import { createModelRegistryLabelsObject } from './utils';
import { ModelRegistryCustomProperties, ModelState, RegisteredModel } from '~/app/types';

type MockRegisteredModelType = {
id?: string;
name?: string;
owner?: string;
state?: ModelState;
description?: string;
labels?: string[];
customProperties?: ModelRegistryCustomProperties;
};

export const mockRegisteredModel = ({
name = 'test',
owner = 'Author 1',
state = ModelState.LIVE,
description = '',
labels = [],
customProperties = {},
id = '1',
}: MockRegisteredModelType): RegisteredModel => ({
createTimeSinceEpoch: '1710404288975',
Expand All @@ -26,5 +25,5 @@ export const mockRegisteredModel = ({
name,
state,
owner,
customProperties: createModelRegistryLabelsObject(labels),
customProperties,
});
48 changes: 22 additions & 26 deletions clients/ui/frontend/src/__mocks__/mockRegisteredModelsList.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { RegisteredModelList } from '~/app/types';
import { ModelRegistryMetadataType, RegisteredModelList } from '~/app/types';
import { mockRegisteredModel } from './mockRegisteredModel';

export const mockRegisteredModelList = ({
Expand All @@ -10,39 +10,35 @@ export const mockRegisteredModelList = ({
name: 'Fraud detection model',
description:
'A machine learning model trained to detect fraudulent transactions in financial data',
labels: [
'Financial data',
'Fraud detection',
'Test label',
'Machine learning',
'Next data to be overflow',
],
customProperties: {
'Financial data': {
metadataType: ModelRegistryMetadataType.STRING,
// eslint-disable-next-line camelcase
string_value: '',
},
},
}),
mockRegisteredModel({
name: 'Credit Scoring',
labels: [
'Credit Score Predictor',
'Creditworthiness scoring system',
'Default Risk Analyzer',
'Portfolio Management',
'Risk Assessment',
],
customProperties: {
'Credit Score Predictor': {
metadataType: ModelRegistryMetadataType.STRING,
// eslint-disable-next-line camelcase
string_value: '',
},
},
}),
mockRegisteredModel({
name: 'Label modal',
description:
'A machine learning model trained to detect fraudulent transactions in financial data',
labels: [
'Testing label',
'Financial data',
'Fraud detection',
'Long label data to be truncated abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc',
'Machine learning',
'Next data to be overflow',
'Label x',
'Label y',
'Label z',
],
customProperties: {
'Testing label': {
metadataType: ModelRegistryMetadataType.STRING,
// eslint-disable-next-line camelcase
string_value: '',
},
},
}),
],
}: Partial<RegisteredModelList>): RegisteredModelList => ({
Expand Down
18 changes: 1 addition & 17 deletions clients/ui/frontend/src/__mocks__/utils.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,4 @@
import {
ModelRegistryMetadataType,
ModelRegistryBody,
ModelRegistryStringCustomProperties,
} from '~/app/types';

export const createModelRegistryLabelsObject = (
labels: string[],
): ModelRegistryStringCustomProperties =>
labels.reduce((acc, label) => {
acc[label] = {
metadataType: ModelRegistryMetadataType.STRING,
// eslint-disable-next-line camelcase
string_value: '',
};
return acc;
}, {} as ModelRegistryStringCustomProperties);
import { ModelRegistryBody } from '~/app/types';

export const mockBFFResponse = <T>(data: T): ModelRegistryBody<T> => ({
data,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { SubComponentBase } from '~/__tests__/cypress/cypress/pages/components/subComponents/SubComponentBase';

export class SearchSelector extends SubComponentBase {
constructor(
private selectorId: string,
contextSelectorId?: string,
) {
super(contextSelectorId);
}

private findContextualItem(suffix: string): Cypress.Chainable<JQuery<HTMLElement>> {
return this.findScope().document().findByTestId(`${this.selectorId}-${suffix}`);
}

findItem(name: string, useMenuList: boolean): Cypress.Chainable<JQuery<HTMLElement>> {
const list = useMenuList ? this.findMenuList() : this.findResultTableList();
return list.contains(name).should('exist');
}

selectItem(name: string, useMenuList = false): void {
this.findItem(name, useMenuList).click();
}

findSearchInput(): Cypress.Chainable<JQuery<HTMLElement>> {
return this.findContextualItem('search');
}

findToggleButton(): Cypress.Chainable<JQuery<HTMLElement>> {
return this.findContextualItem('toggle');
}

findResultTableList(): Cypress.Chainable<JQuery<HTMLElement>> {
return this.findContextualItem('table-list');
}

findSearchHelpText(): Cypress.Chainable<JQuery<HTMLElement>> {
return this.findContextualItem('searchHelpText');
}

findMenu(): Cypress.Chainable<JQuery<HTMLElement>> {
return this.findContextualItem('menu');
}

findMenuList(): Cypress.Chainable<JQuery<HTMLElement>> {
return this.findContextualItem('menuList');
}

// Search for an item by typing into the search input
searchItem(name: string): void {
this.findSearchInput().clear().type(name);
}

// Perform the entire process: open, search, and select
openAndSelectItem(name: string, useMenuList = false): void {
this.findToggleButton().click();
this.searchItem(name);
this.selectItem(name, useMenuList);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/**
* A SubComponent is a component that doesn't make up a full page and will be consumed in other page
* objects. This could be a complex field, a group of fields, or some section. Typically not large
* enough to warrant its own standalone page object.
*
* Primary use-case example:
* class Foo extends SubComponentBase {
* constructor(private myTestId: string, scopedTestId?: string) {
* super(scopedTestId);
* }
*
* private find(suffix: string) {
* return this.findScope().getByTestId(`${this.myTestId}-${suffix}`);
* }
*
* selectItem(name: string) {
* // "list" would be an internal suffix for your component to know where the "items" are
* return this.find('list').findDropdownItem(name);
* }
* }
*
* Search uses of this component to see further examples
*/
export class SubComponentBase {
constructor(private scopedBaseTestId?: string) {}

/** Allows for extended classes to make use of a simple one-check for their `find()` calls */
protected findScope(): (Cypress.cy & CyEventEmitter) | Cypress.Chainable<JQuery<HTMLElement>> {
if (this.scopedBaseTestId) {
return cy.findByTestId(this.scopedBaseTestId);
}

return cy;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -87,14 +87,38 @@ class ModelRegistry {
return cy.findByTestId('empty-model-registries-state');
}

findModelRegistryEmptyTableState() {
return cy.findByTestId('dashboard-empty-table-state');
}

shouldregisteredModelsEmpty() {
cy.findByTestId('empty-registered-models').should('exist');
}

findViewDetailsButton() {
return cy.findByTestId('view-details-button');
}

findDetailsPopover() {
return cy.findByTestId('mr-details-popover');
}

findHelpContentButton() {
return cy.findByTestId('model-registry-help-button');
}

findHelpContentPopover() {
return cy.findByTestId('model-registry-help-content');
}

shouldmodelVersionsEmpty() {
cy.findByTestId('empty-model-versions').should('exist');
}

shouldArchiveModelVersionsEmpty() {
cy.findByTestId('empty-archive-model-versions').should('exist');
}

shouldModelRegistrySelectorExist() {
cy.findByTestId('model-registry-selector-dropdown').should('exist');
}
Expand All @@ -103,10 +127,6 @@ class ModelRegistry {
cy.findByTestId('registered-models-table-toolbar').should('exist');
}

shouldArchiveModelVersionsEmpty() {
cy.findByTestId('empty-archive-model-versions').should('exist');
}

tabEnabled() {
appChrome.findNavItem('Model Registry').should('exist');
return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,14 @@ class ModelVersionArchive {
return cy.findByTestId('archive-version-page-breadcrumb');
}

findVersionDetailsTab() {
return cy.findByTestId('model-versions-details-tab');
}

findVersionDeploymentTab() {
return cy.findByTestId('deployments-tab');
}

findArchiveVersionTable() {
return cy.findByTestId('model-versions-archive-table');
}
Expand Down
Loading
Loading