Skip to content

Commit

Permalink
Revamp empty state in Model Serving Global
Browse files Browse the repository at this point in the history
  • Loading branch information
lucferbux committed Sep 18, 2023
1 parent 5e2239a commit dc1f4ca
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 16 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,36 @@
import { test, expect } from '@playwright/test';
import { navigateToStory } from '~/__tests__/integration/utils';

test('Delete model', async ({ page }) => {
test('Empty State No Serving Runtime', async ({ page }) => {
await page.goto(
'./iframe.html?args=&id=tests-integration-pages-modelserving-modelservingglobal--delete-model&viewMode=story',
navigateToStory('modelserving-modelservingglobal', 'empty-state-no-serving-runtime'),
);

// wait for page to load
await page.waitForSelector('text=No deployed models yet');

// Test that the button is enabled
await expect(page.getByRole('button', { name: 'Go to the Projects page' })).toBeTruthy();
});

test('Empty State No Inference Service', async ({ page }) => {
await page.goto(
navigateToStory('modelserving-modelservingglobal', 'empty-state-no-inference-service'),
);

// wait for page to load
await page.waitForSelector('text=No deployed models');

// Test that the button is enabled
await page.getByRole('button', { name: 'Deploy model' }).click();

// test that you can not submit on empty
await expect(await page.getByRole('button', { name: 'Deploy' })).toBeDisabled();
});

test('Delete model', async ({ page }) => {
await page.goto(navigateToStory('modelserving-modelservingglobal', 'delete-model'));

// wait for page to load
await page.waitForSelector('text=Delete deployed model?');

Expand All @@ -19,9 +45,7 @@ test('Delete model', async ({ page }) => {
});

test('Edit model', async ({ page }) => {
await page.goto(
'./iframe.html?args=&id=tests-integration-pages-modelserving-modelservingglobal--edit-model&viewMode=story',
);
await page.goto(navigateToStory('modelserving-modelservingglobal', 'edit-model'));

// wait for page to load
await page.waitForSelector('text=Deploy model');
Expand Down Expand Up @@ -53,9 +77,7 @@ test('Edit model', async ({ page }) => {
});

test('Create model', async ({ page }) => {
await page.goto(
'./iframe.html?args=&id=tests-integration-pages-modelserving-modelservingglobal--deploy-model&viewMode=story',
);
await page.goto(navigateToStory('modelserving-modelservingglobal', 'deploy-model'));

// wait for page to load
await page.waitForSelector('text=Deploy model');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,59 @@ const Template: StoryFn<typeof ModelServingGlobal> = (args) => (
</Routes>
);

export const EmptyStateNoServingRuntime: StoryObj = {
render: Template,

parameters: {
a11y: {
// need to select modal as root
element: '.pf-c-backdrop',
},
msw: {
handlers: [
rest.get(
'api/k8s/apis/serving.kserve.io/v1alpha1/namespaces/test-project/servingruntimes',
(req, res, ctx) => res(ctx.json(mockK8sResourceList([]))),
),
rest.get(
'api/k8s/apis/serving.kserve.io/v1beta1/namespaces/test-project/inferenceservices',
(req, res, ctx) => res(ctx.json(mockK8sResourceList([]))),
),
rest.get('/api/k8s/apis/project.openshift.io/v1/projects', (req, res, ctx) =>
res(ctx.json(mockK8sResourceList([mockProjectK8sResource({})]))),
),
],
},
},
};

export const EmptyStateNoInferenceServices: StoryObj = {
render: Template,

parameters: {
a11y: {
// need to select modal as root
element: '.pf-c-backdrop',
},
msw: {
handlers: [
rest.get(
'api/k8s/apis/serving.kserve.io/v1alpha1/namespaces/test-project/servingruntimes',
(req, res, ctx) =>
res(ctx.json(mockK8sResourceList([mockServingRuntimeK8sResource({})]))),
),
rest.get(
'api/k8s/apis/serving.kserve.io/v1beta1/namespaces/test-project/inferenceservices',
(req, res, ctx) => res(ctx.json(mockK8sResourceList([]))),
),
rest.get('/api/k8s/apis/project.openshift.io/v1/projects', (req, res, ctx) =>
res(ctx.json(mockK8sResourceList([mockProjectK8sResource({})]))),
),
],
},
},
};

export const EditModel: StoryObj = {
render: Template,

Expand Down
2 changes: 2 additions & 0 deletions frontend/src/__tests__/integration/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const navigateToStory = (folder: string, storyId: string) =>
`./iframe.html?args=&id=tests-integration-pages-${folder}--${storyId}&viewMode=story`;
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
import * as React from 'react';
import { Button, EmptyState, EmptyStateBody, EmptyStateIcon, Title } from '@patternfly/react-core';
import { PlusCircleIcon } from '@patternfly/react-icons';
import {
Button,
EmptyState,
EmptyStateBody,
EmptyStateIcon,
EmptyStateVariant,
Title,
} from '@patternfly/react-core';
import { PlusCircleIcon, WrenchIcon } from '@patternfly/react-icons';
import { useNavigate } from 'react-router-dom';
import { ModelServingContext } from '~/pages/modelServing/ModelServingContext';
import ServeModelButton from './ServeModelButton';
Expand All @@ -13,16 +20,17 @@ const EmptyModelServing: React.FC = () => {

if (servingRuntimes.length === 0) {
return (
<EmptyState>
<EmptyStateIcon icon={PlusCircleIcon} />
<EmptyState variant={EmptyStateVariant.small}>
<EmptyStateIcon icon={WrenchIcon} />
<Title headingLevel="h2" size="lg">
No model servers
No deployed models yet
</Title>
<EmptyStateBody>
Before deploying a model, you must first configure a model server.
To deploy a model, go to the Projects page and select the project from which the model
will be deployed. Then jump down to the Models and Model Servers section.
</EmptyStateBody>
<Button variant="primary" onClick={() => navigate('/projects')}>
Create server
<Button variant="link" onClick={() => navigate('/projects')}>
Go to the Projects page
</Button>
</EmptyState>
);
Expand Down

0 comments on commit dc1f4ca

Please sign in to comment.