Skip to content

Commit

Permalink
Added Functions tab to left navigation menu in Dev perspective
Browse files Browse the repository at this point in the history
  • Loading branch information
lprabhu committed Sep 8, 2023
1 parent b5aa690 commit 2ed88e7
Show file tree
Hide file tree
Showing 26 changed files with 585 additions and 43 deletions.
Expand Up @@ -20,6 +20,7 @@ export const useTabbedTableBreadcrumbsFor = (
subTab: string = null,
customBreadcrumbName?: string,
customBreadcrumbURLRequired?: boolean,
customBreadCrumbDetailsPrefix?: string,
) => {
const { t } = useTranslation();
const { label, labelKey, labelPlural, labelPluralKey } = kindObj;
Expand All @@ -39,7 +40,7 @@ export const useTabbedTableBreadcrumbsFor = (
},
{
name: t('console-shared~{{label}} details', {
label: labelKey ? t(labelKey) : label,
label: customBreadCrumbDetailsPrefix || (labelKey ? t(labelKey) : label),
}),
path: match.url,
},
Expand All @@ -48,6 +49,7 @@ export const useTabbedTableBreadcrumbsFor = (
subTab,
customBreadcrumbName,
customBreadcrumbURLRequired,
customBreadCrumbDetailsPrefix,
labelPluralKey,
t,
labelPlural,
Expand Down
3 changes: 2 additions & 1 deletion frontend/packages/dev-console/console-extensions.json
Expand Up @@ -1046,7 +1046,8 @@
"/helm-releases",
"/upload-jar",
"/search-page",
"/builds"
"/builds",
"/functions"
],
"component": { "$codeRef": "common.NamespaceRedirect" }
}
Expand Down
Expand Up @@ -17,6 +17,7 @@ export enum devNavigationMenu {
Routes = 'Routes',
Deployments = 'Deployments',
Consoles = 'Consoles',
Functions = 'Functions',
}

export enum adminNavigationBar {
Expand Down
Expand Up @@ -62,4 +62,5 @@ export const pageTitle = {
Samples: 'Samples',
CreateServerlessFunction: 'Create Serverless function',
AddGitRepository: 'Add Git Repository',
Functions: 'Functions',
};
Expand Up @@ -12,6 +12,7 @@ export const devNavigationMenuPO = {
secret: '#Secret',
dropdownButton: '[data-test-id="dropdown-button"]',
environments: '[data-test-id="environments-header"]',
functions: '[data-test-id="functions-details-header"]',
};

export const adminNavigationMenuPO = {
Expand Down
Expand Up @@ -235,6 +235,12 @@ export const navigateTo = (opt: devNavigationMenu) => {
cy.testA11y('cluster Page in dev perspective');
break;
}
case devNavigationMenu.Functions: {
cy.get(devNavigationMenuPO.functions).click();
detailsPage.titleShouldContain(pageTitle.Functions);
cy.testA11y('Functions Page in dev perspective');
break;
}
default: {
throw new Error('Option is not available');
}
Expand Down
Expand Up @@ -15,7 +15,9 @@ export const createGitWorkload = (
gitPage.enterGitUrl(gitUrl);
gitPage.verifyValidatedMessage(gitUrl);
gitPage.enterComponentName(componentName);
gitPage.selectResource(resourceType);
if (resourceType !== 'Serverless Function') {
gitPage.selectResource(resourceType);
}
gitPage.enterAppName(appName);
if (isPipelineSelected === true) {
gitPage.selectAddPipeline();
Expand Down
Expand Up @@ -13,6 +13,7 @@ export enum NavigationMenu {
ProjectDetails = 'Project Details',
ProjectAccess = 'Project Access',
Pipelines = 'Pipelines',
Functions = 'Functions',
}

export enum Perspective {
Expand Down Expand Up @@ -72,6 +73,12 @@ export const naviagteTo = async function (opt: NavigationMenu) {
await browser.wait(EC.urlContains('project-access'), ELEMENT_WAIT);
break;
}
case NavigationMenu.Functions: {
await click($('a.pf-c-nav__link[data-component="pf-nav-expandable"]'));
await click($('[data-test-id="functions-details-header"]'));
await browser.wait(EC.urlContains('functions'), ELEMENT_WAIT);
break;
}
default: {
throw new Error('Option is not available');
}
Expand Down
61 changes: 61 additions & 0 deletions frontend/packages/knative-plugin/console-extensions.json
Expand Up @@ -409,6 +409,67 @@
"required": ["KNATIVE_SERVING"]
}
},
{
"type": "console.page/route",
"properties": {
"exact": true,
"path": ["/functions/all-namespaces", "/functions/ns/:ns"],
"component": {
"$codeRef": "overviewComponent.FunctionsPage"
}
},
"flags": {
"required": ["KNATIVE_SERVING"]
}
},
{
"type": "console.page/route",
"properties": {
"exact": true,
"path": ["/functions"],
"component": {
"$codeRef": "knativeComponent.NamespaceRedirect"
}
},
"flags": {
"required": ["KNATIVE_SERVING"]
}
},
{
"type": "console.navigation/href",
"properties": {
"id": "functions",
"perspective": "dev",
"section": "resources",
"name": "%knative-plugin~Functions%",
"href": "/functions",
"namespaced": true,
"insertBefore": "builds",
"dataAttributes": {
"data-quickstart-id": "qs-nav-functions",
"data-test-id": "functions-details-header"
}
},
"flags": {
"required": ["OPENSHIFT", "KNATIVE_SERVING", "KNATIVE_SERVING_SERVICE"]
}
},
{
"type": "console.page/route",
"properties": {
"exact": false,
"path": ["/functions/ns/:ns/:name"],
"model": {
"group": "serving.knative.dev",
"version": "v1",
"kind": "Service"
},
"component": { "$codeRef": "overviewComponent.FunctionDetailsPage" }
},
"flags": {
"required": ["OPENSHIFT", "KNATIVE_SERVING", "KNATIVE_SERVING_SERVICE"]
}
},
{
"type": "console.page/route",
"properties": {
Expand Down
@@ -0,0 +1,32 @@
@knative-serverless @knative
Feature: Navigations to Serverless Functions page
As a user, I want to navigate to Serverless functions page in developer perspective

Background:
Given user is at developer perspective
And user has created or selected namespace "aut-knative-functions"


@smoke
Scenario: User navigates to Functions page when no Function is created: KN-08-TC01
When user clicks on the Functions tab
Then user redirected to Functions page
And user is able to see the message "No Functions found"

@smoke
Scenario: User navigates to Functions page when Function is created: KN-08-TC02
Given user has created a serverless function using repo "https://github.com/Lucifergene/serverless-func-repo" with name "serverless-func-test-repo"
When user clicks on the Functions tab
Then user redirected to Functions page
And user will see the serverless functions listed


@smoke
Scenario: User navigates to Function details page: KN-08-TC03
Given user clicks on the Functions tab
When user clicks on the function name "serverless-func-test-repo"
Then user will see the Details page opened
And user is able to see service URL and Revisions details
And user is able to see Containers sections


@@ -0,0 +1,5 @@
export const functionsPO = {
emptyState: 'div.pf-c-empty-state__content',
table: '[role="grid"]',
search: '[data-test-id="item-filter"]',
};
@@ -0,0 +1,18 @@
import { functionsPO } from '../../pageObjects/functions-po';

export const functionsPage = {
verifyTitle: () => cy.byTestSectionHeading('Service details').should('be.visible'),
verifyMessage: (noFunctionsFound: string) =>
cy.get(functionsPO.emptyState).contains(noFunctionsFound),
verifyFunctionsListed: () => {
cy.get(functionsPO.table).get('table').its('length').should('be.greaterThan', 0);
},
clickFunctionName: (name: string) => cy.get(`a[title="${name}"]`).click(),
search: (name: string) => {
cy.get(functionsPO.search).clear().type(name);
},
verifyServiceURL: () => cy.byTestID('URL').should('be.visible'),
verifyServiceRevision: () => cy.byTestID('Revisions').should('be.visible'),
verifyContainerSection: () =>
cy.get('[data-test-section-heading="Containers"]').should('be.visible'),
};
@@ -0,0 +1,63 @@
import { Given, When, Then } from 'cypress-cucumber-preprocessor/steps';
import { detailsPage } from '@console/cypress-integration-tests/views/details-page';
import {
devNavigationMenu,
switchPerspective,
} from '@console/dev-console/integration-tests/support/constants';
import {
createGitWorkloadIfNotExistsOnTopologyPage,
navigateTo,
perspective,
} from '@console/dev-console/integration-tests/support/pages';
import { functionsPage } from '../../pages/functions/functions-page';

Given('user is at developer perspective', () => {
perspective.switchTo(switchPerspective.Developer);
});

When('user clicks on the Functions tab', () => {
navigateTo(devNavigationMenu.Functions);
});

Then('user redirected to Functions page', () => {
detailsPage.titleShouldContain('Functions');
});

Then('user is able to see the message {string}', (noFunctionsFound: string) => {
functionsPage.verifyMessage(noFunctionsFound);
});

Given(
'user has created a serverless function using repo {string} with name {string}',
(gitRepo: string, name: string) => {
createGitWorkloadIfNotExistsOnTopologyPage(
gitRepo,
name,
'Serverless Function',
`${name}-app`,
false,
);
},
);

Then('user will see the serverless functions listed', () => {
functionsPage.verifyFunctionsListed();
});

When('user clicks on the function name {string}', (functionName: string) => {
functionsPage.search(functionName);
functionsPage.clickFunctionName(functionName);
});

Then('user will see the Details page opened', () => {
functionsPage.verifyTitle();
});

Then('user is able to see service URL and Revisions details', () => {
functionsPage.verifyServiceURL();
functionsPage.verifyServiceRevision();
});

Then('user is able to see Containers sections', () => {
functionsPage.verifyContainerSection();
});
@@ -1,4 +1,5 @@
{
"Functions": "Functions",
"Eventing": "Eventing",
"Event Source": "Event Source",
"Create an Event source to register interest in a class of events from a particular system": "Create an Event source to register interest in a class of events from a particular system",
Expand Down Expand Up @@ -76,6 +77,7 @@
"Set traffic distribution": "Set traffic distribution",
"Move {{kind}}": "Move {{kind}}",
"Edit {{applicationName}}": "Edit {{applicationName}}",
"Edit Service": "Edit Service",
"Move sink": "Move sink",
"Delete Revision": "Delete Revision",
"Edit URI": "Edit URI",
Expand Down Expand Up @@ -197,6 +199,7 @@
"{{OKcount}} OK / {{conditionsSize}}": "{{OKcount}} OK / {{conditionsSize}}",
"Subscriber": "Subscriber",
"Filters": "Filters",
"Select a Project to view its details<1></1>.": "Select a Project to view its details<1></1>.",
"There is an existing placeholder Service with name {{name}} in namespace {{namespace}}. Please provide another name": "There is an existing placeholder Service with name {{name}} in namespace {{namespace}}. Please provide another name",
"This feature will create a new serverless deployment next to your existing deployment. Other configurations, including the traffic pattern, can be modified in the form.": "This feature will create a new serverless deployment next to your existing deployment. Other configurations, including the traffic pattern, can be modified in the form.",
"No configurations found for this resource.": "No configurations found for this resource.",
Expand Down Expand Up @@ -242,7 +245,10 @@
"Route details": "Route details",
"URL": "URL",
"Traffic": "Traffic",
"Service details": "Service details",
"Containers": "Containers",
"Generation": "Generation",
"Non-functions": "Non-functions",
"Connects <strong>{{resourceName}}</strong> to": "Connects <1>{{resourceName}}</1> to",
"Select a sink": "Select a sink",
"Save": "Save",
Expand Down
29 changes: 28 additions & 1 deletion frontend/packages/knative-plugin/src/actions/creators.ts
@@ -1,7 +1,8 @@
import i18next from 'i18next';
import { Action } from '@console/dynamic-plugin-sdk';
import { resourceObjPath } from '@console/internal/components/utils';
import { truncateMiddle } from '@console/internal/components/utils/truncate-middle';
import { K8sKind, K8sResourceKind } from '@console/internal/module/k8s';
import { K8sKind, K8sResourceKind, referenceForModel } from '@console/internal/module/k8s';
import { RESOURCE_NAME_TRUNCATE_LENGTH } from '@console/shared/src/constants';
import {
setSinkPubsubModal,
Expand All @@ -13,6 +14,7 @@ import {
} from '../components/modals';
import { addPubSubConnectionModal } from '../components/pub-sub/PubSubModalLauncher';
import { EventingSubscriptionModel, EventingTriggerModel } from '../models';
import { ServiceTypeValue } from '../types';

export const setTrafficDistribution = (kind: K8sKind, obj: K8sResourceKind): Action => ({
id: 'set-traffic-distribution',
Expand Down Expand Up @@ -101,6 +103,31 @@ export const editKnativeService = (kind: K8sKind, obj: K8sResourceKind): Action
},
});

export const editKnativeServiceResource = (
kind: K8sKind,
obj: K8sResourceKind,
serviceTypeValue: ServiceTypeValue,
): Action => {
return {
id: 'edit-service',
label: i18next.t('knative-plugin~Edit Service'),
cta: {
href:
serviceTypeValue === ServiceTypeValue.Functions
? `/functions/ns/${obj.metadata.namespace}/${obj.metadata.name}/yaml`
: `${resourceObjPath(obj, kind.crd ? referenceForModel(kind) : kind.kind)}/yaml`,
},
insertAfter: 'edit-annotations',
accessReview: {
group: kind.apiGroup,
resource: kind.plural,
name: obj.metadata.name,
namespace: obj.metadata.namespace,
verb: 'update',
},
};
};

export const moveSinkSource = (model: K8sKind, source: K8sResourceKind): Action => ({
id: 'move-sink-source',
label: i18next.t('knative-plugin~Move sink'),
Expand Down

0 comments on commit 2ed88e7

Please sign in to comment.