-
Notifications
You must be signed in to change notification settings - Fork 65
OU-1212: Create initial observability landing page with summary cards #1112
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
Open
jeff-phillips-18
wants to merge
1
commit into
openshift:main
Choose a base branch
from
jeff-phillips-18:services-landing-page
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| [ | ||
| { | ||
| "op": "add", | ||
| "path": "/extensions/0", | ||
| "value": { | ||
| "type": "console.navigation/href", | ||
| "properties": { | ||
| "id": "services", | ||
| "name": "%plugin__monitoring-plugin~Observability services%", | ||
| "href": "/monitoring/services", | ||
| "perspective": "admin", | ||
| "section": "observe" | ||
| } | ||
| } | ||
| }, | ||
| { | ||
| "op": "add", | ||
| "path": "/extensions/0", | ||
| "value": { | ||
| "type": "console.page/route", | ||
| "properties": { | ||
| "exact": false, | ||
| "path": "/monitoring/services", | ||
| "component": { | ||
| "$codeRef": "ServicesPage.MpCmoServicesPage" | ||
| } | ||
| } | ||
| } | ||
| } | ||
| ] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,64 @@ | ||
| package server | ||
|
|
||
| import ( | ||
| "encoding/json" | ||
| "path/filepath" | ||
| "testing" | ||
|
|
||
| "github.com/stretchr/testify/require" | ||
| ) | ||
|
|
||
| func TestPatchManifestServices(t *testing.T) { | ||
| baseManifest := []byte(`{ | ||
| "name": "monitoring-plugin", | ||
| "extensions": [] | ||
| }`) | ||
| configPath := filepath.Join("..", "..", "config") | ||
|
|
||
| t.Run("enabled adds services navigation and route", func(t *testing.T) { | ||
| patched := patchManifest(baseManifest, &Config{ | ||
| ConfigPath: configPath, | ||
| Features: map[Feature]bool{ | ||
| Services: true, | ||
| }, | ||
| }) | ||
|
|
||
| var manifest struct { | ||
| Extensions []struct { | ||
| Type string `json:"type"` | ||
| Properties struct { | ||
| ID string `json:"id"` | ||
| Path string `json:"path"` | ||
| Href string `json:"href"` | ||
| } `json:"properties"` | ||
| } `json:"extensions"` | ||
| } | ||
| require.NoError(t, json.Unmarshal(patched, &manifest)) | ||
|
|
||
| var hasNav, hasRoute bool | ||
| for _, ext := range manifest.Extensions { | ||
| if ext.Type == "console.navigation/href" && ext.Properties.ID == "services" { | ||
| hasNav = true | ||
| require.Equal(t, "/monitoring/services", ext.Properties.Href) | ||
| } | ||
| if ext.Type == "console.page/route" && ext.Properties.Path == "/monitoring/services" { | ||
| hasRoute = true | ||
| } | ||
| } | ||
| require.True(t, hasNav, "expected services navigation item in patched manifest") | ||
| require.True(t, hasRoute, "expected services route in patched manifest") | ||
| }) | ||
|
|
||
| t.Run("disabled leaves services patch absent", func(t *testing.T) { | ||
| patched := patchManifest(baseManifest, &Config{ | ||
| ConfigPath: configPath, | ||
| Features: map[Feature]bool{ | ||
| Services: false, | ||
| }, | ||
| }) | ||
|
|
||
| require.JSONEq(t, string(baseManifest), string(patched)) | ||
| require.NotContains(t, string(patched), `"id": "services"`) | ||
| require.NotContains(t, string(patched), "/monitoring/services") | ||
| }) | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,76 @@ | ||
| import { MemoryRouter } from 'react-router'; | ||
|
|
||
| import SummaryCard from '@/features/services/components/summary/SummaryCard'; | ||
| import { DataTestIDs } from '@/shared/constants/data-test'; | ||
|
|
||
| const mountCard = (props: { | ||
| count: number; | ||
| title: string; | ||
| url: string; | ||
| cardId: string; | ||
| loading?: boolean; | ||
| error?: string; | ||
| }) => { | ||
| cy.mount( | ||
| <MemoryRouter> | ||
| <SummaryCard {...props} /> | ||
| </MemoryRouter>, | ||
| ); | ||
| }; | ||
|
|
||
| describe('SummaryCard', () => { | ||
| it('renders title and count, and navigates on click', () => { | ||
| mountCard({ | ||
| cardId: 'metrics', | ||
| count: 42, | ||
| title: 'Metrics', | ||
| url: '/monitoring/query-browser', | ||
| }); | ||
|
|
||
| cy.get(`[data-test="${DataTestIDs.ServicesPage.SummaryCard}-metrics"]`).should('be.visible'); | ||
| cy.contains('h3', 'Metrics').should('be.visible'); | ||
| cy.get(`[data-test="${DataTestIDs.ServicesPage.SummaryCardCount}-metrics"]`) | ||
| .should('be.visible') | ||
| .should('contain.text', '42') | ||
| .click(); | ||
|
|
||
| cy.location('pathname').should('eq', '/monitoring/query-browser'); | ||
| }); | ||
|
|
||
| it('renders loading state', () => { | ||
| mountCard({ | ||
| cardId: 'targets', | ||
| count: 0, | ||
| title: 'Targets', | ||
| url: '/monitoring/targets', | ||
| loading: true, | ||
| }); | ||
|
|
||
| cy.get(`[data-test="${DataTestIDs.ServicesPage.SummaryCardLoading}-targets"]`).should( | ||
| 'be.visible', | ||
| ); | ||
| cy.get(`[data-test="${DataTestIDs.ServicesPage.SummaryCardCount}-targets"]`).should( | ||
| 'not.exist', | ||
| ); | ||
| cy.get(`[data-test="${DataTestIDs.ServicesPage.SummaryCardError}-targets"]`).should( | ||
| 'not.exist', | ||
| ); | ||
| }); | ||
|
|
||
| it('renders error state', () => { | ||
| mountCard({ | ||
| cardId: 'dashboards', | ||
| count: 0, | ||
| title: 'Perses Dashboards', | ||
| url: '/monitoring/v2/dashboards', | ||
| error: 'Failed to fetch dashboards', | ||
| }); | ||
|
|
||
| cy.get(`[data-test="${DataTestIDs.ServicesPage.SummaryCardError}-dashboards"]`).should( | ||
| 'be.visible', | ||
| ); | ||
| cy.get(`[data-test="${DataTestIDs.ServicesPage.SummaryCardCount}-dashboards"]`).should( | ||
| 'not.exist', | ||
| ); | ||
| }); | ||
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
30 changes: 30 additions & 0 deletions
30
web/cypress/e2e/monitoring/regression/04.reg_services_admin.cy.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| import { runAllRegressionServicesTests } from '../../../support/monitoring/04.reg_services.cy'; | ||
| import { commonPages } from '../../../views/common'; | ||
| import { nav } from '../../../views/nav'; | ||
| import { servicesPage } from '../../../views/services-page'; | ||
|
|
||
| const MP = { | ||
| namespace: 'openshift-monitoring', | ||
| operatorName: 'Cluster Monitoring Operator', | ||
| }; | ||
|
|
||
| describe( | ||
| 'Regression: Monitoring - Observability services (Administrator)', | ||
| { tags: ['@monitoring', '@services'] }, | ||
| () => { | ||
| before(() => { | ||
| cy.beforeBlock(MP); | ||
| }); | ||
|
|
||
| beforeEach(() => { | ||
| nav.sidenav.clickNavLink(['Observe', 'Metrics']); | ||
| commonPages.titleShouldHaveText('Metrics'); | ||
| servicesPage.clearInfoAlertDismissed(); | ||
| servicesPage.goTo(); | ||
| }); | ||
|
|
||
| runAllRegressionServicesTests({ | ||
| name: 'Administrator', | ||
| }); | ||
| }, | ||
| ); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,87 @@ | ||
| import { commonPages } from '../../views/common'; | ||
| import { servicesPage, ServicesSummaryCardId } from '../../views/services-page'; | ||
|
|
||
| export interface PerspectiveConfig { | ||
| name: string; | ||
| beforeEach?: () => void; | ||
| } | ||
|
|
||
| const ALL_CARDS: ServicesSummaryCardId[] = [ | ||
| 'dashboards', | ||
| 'alerting-rules', | ||
| 'firing-alerts', | ||
| 'targets', | ||
| 'metrics', | ||
| ]; | ||
|
|
||
| export function runAllRegressionServicesTests(perspective: PerspectiveConfig) { | ||
| testServicesRegression(perspective); | ||
| } | ||
|
|
||
| export function testServicesRegression(perspective: PerspectiveConfig) { | ||
| it(`${perspective.name} perspective - Observability services page`, () => { | ||
| cy.log('1.1 Navigate to Observability services and verify page chrome'); | ||
| servicesPage.clearInfoAlertDismissed(); | ||
| servicesPage.goTo(); | ||
| servicesPage.shouldBeLoaded(); | ||
| cy.contains( | ||
| 'Manage and monitor your metrics, logs, and traces from a single, unified hub.', | ||
| ).should('be.visible'); | ||
|
|
||
| cy.log('1.2 Verify info alert is visible and dismissible with localStorage persistence'); | ||
| servicesPage.elements.infoAlert().should('be.visible'); | ||
| servicesPage.elements.infoAlert().should('contain.text', 'Cluster-wide observability scope'); | ||
| servicesPage.dismissInfoAlert(); | ||
| cy.window() | ||
| .its('localStorage') | ||
| .invoke('getItem', 'monitoring/services/info-alert-dismissed') | ||
| .should('eq', 'true'); | ||
|
|
||
| cy.log('1.3 Reload and verify dismissed alert stays hidden'); | ||
| servicesPage.goTo(); | ||
| servicesPage.elements.infoAlert().should('not.exist'); | ||
| servicesPage.elements.summarySection().should('be.visible'); | ||
|
|
||
| cy.log('1.4 Verify all summary cards finish loading'); | ||
| ALL_CARDS.forEach((cardId) => { | ||
| servicesPage.assertSummaryCardReady(cardId); | ||
| }); | ||
| servicesPage.elements.summaryCard('alerting-rules').should('contain.text', 'Alerting rules'); | ||
| servicesPage.elements.summaryCard('firing-alerts').should('contain.text', 'Firing alerts'); | ||
| servicesPage.elements.summaryCard('targets').should('contain.text', 'Targets'); | ||
| servicesPage.elements.summaryCard('metrics').should('contain.text', 'Metrics'); | ||
| servicesPage.elements.summaryCard('dashboards').should('contain.text', 'Perses Dashboards'); | ||
|
|
||
| cy.log('1.5 Click Firing alerts count and verify Alerting page'); | ||
| servicesPage.goTo(); | ||
| servicesPage.clickSummaryCardCount('firing-alerts'); | ||
| commonPages.titleShouldHaveText('Alerting'); | ||
|
|
||
| cy.log('1.6 Click Alerting rules count and verify Alerting page'); | ||
| servicesPage.goTo(); | ||
| servicesPage.clickSummaryCardCount('alerting-rules'); | ||
| commonPages.titleShouldHaveText('Alerting'); | ||
|
|
||
| cy.log('1.7 Click Targets count and verify Metrics targets page'); | ||
| servicesPage.goTo(); | ||
| servicesPage.clickSummaryCardCount('targets'); | ||
| commonPages.titleShouldHaveText('Metrics targets'); | ||
|
|
||
| cy.log('1.8 Click Metrics count and verify Metrics page'); | ||
| servicesPage.goTo(); | ||
| servicesPage.clickSummaryCardCount('metrics'); | ||
| commonPages.titleShouldHaveText('Metrics'); | ||
|
|
||
| cy.log( | ||
| '1.9 Click Perses Dashboards count when available (may be error-only without COO/Perses)', | ||
| ); | ||
| servicesPage.goTo(); | ||
| servicesPage.clickSummaryCardCountIfAvailable('dashboards').then((navigated) => { | ||
| if (navigated) { | ||
| cy.url().should('include', '/monitoring/v2/dashboards'); | ||
| } | ||
| }); | ||
|
|
||
| cy.log('Verified: Observability services page load, alert dismiss, and card navigation'); | ||
| }); | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not sure why this is needed? can you clarify?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is following the pattern for the other nav sections for running a suite of regression tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cc @etmurasaki can you check?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it is fine the structure he followed... I have more comments to make about beforeEach section and other scenario in the support file, but I will wait for the discussion on the thread to proceed with the review