Skip to content

Commit c207a75

Browse files
authored
[Backport main] Add new test suite and workflow for left navigation menu (#1710)
* Add new test suite and workflow for left navigation menu Signed-off-by: Owen Wang <[email protected]> * Fix missing config for disable workspace Signed-off-by: Owen Wang <[email protected]> * Remove tenancy config for left navigation workflow Signed-off-by: Owen Wang <[email protected]> * Address comments by adding additional assertion to navigation menu Signed-off-by: Owen Wang <[email protected]> * Add new test suite and workflow for left navigation menu in 2.x (#1707) * Add new test suite and workflow for left navigation menu Signed-off-by: Owen Wang <[email protected]> * Fix missing config for disable workspace Signed-off-by: Owen Wang <[email protected]> * Address comments by adding additional assertion to navigation menu Signed-off-by: Owen Wang <[email protected]> * Fix lint issue in dashboards test cases Signed-off-by: Owen Wang <[email protected]> --------- Signed-off-by: Owen Wang <[email protected]> (cherry picked from commit 947aaa0) --------- Signed-off-by: Owen Wang <[email protected]>
1 parent 2b57298 commit c207a75

File tree

4 files changed

+377
-3
lines changed

4 files changed

+377
-3
lines changed
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
name: Left Navigation Release tests workflow in Bundled OpenSearch Dashboards
2+
on:
3+
pull_request:
4+
branches: ['**']
5+
6+
jobs:
7+
changes:
8+
runs-on: ubuntu-latest
9+
outputs:
10+
tests: ${{ steps.filter.outputs.tests }}
11+
steps:
12+
- uses: dorny/paths-filter@v2
13+
id: filter
14+
with:
15+
filters: |
16+
tests:
17+
- 'cypress/**/left-navigation/**'
18+
tests-workspace-enabled-with-security:
19+
needs: changes
20+
if: ${{ needs.changes.outputs.tests == 'true' }}
21+
uses: ./.github/workflows/release-e2e-workflow-template.yml
22+
with:
23+
test-name: left navigation workspace enabled with security
24+
test-command: env CYPRESS_WORKSPACE_ENABLED=true CYPRESS_SAVED_OBJECTS_PERMISSION_ENABLED=true yarn cypress:run-with-security --browser chromium --spec 'cypress/integration/core-opensearch-dashboards/opensearch-dashboards/left-navigation/*'
25+
osd-serve-args: --workspace.enabled=true --savedObjects.permission.enabled=true --opensearch_security.multitenancy.enabled=false --opensearchDashboards.dashboardAdmin.users='["admin"]' --uiSettings.overrides.home:useNewHomePage=true
26+
artifact-name-suffix: '-workspace-enabled-with-security'
27+
tests-workspace-enabled-without-security:
28+
needs: changes
29+
if: ${{ needs.changes.outputs.tests == 'true' }}
30+
uses: ./.github/workflows/release-e2e-workflow-template.yml
31+
with:
32+
test-name: left navigation workspace enabled without security
33+
test-command: env CYPRESS_WORKSPACE_ENABLED=true yarn cypress:run-without-security --browser chromium --spec 'cypress/integration/core-opensearch-dashboards/opensearch-dashboards/left-navigation/*'
34+
osd-serve-args: --workspace.enabled=true --savedObjects.permission.enabled=false --uiSettings.overrides.home:useNewHomePage=true
35+
security-enabled: false
36+
artifact-name-suffix: '-workspace-enabled-without-security'
37+
tests-workspace-disabled-with-security:
38+
needs: changes
39+
if: ${{ needs.changes.outputs.tests == 'true' }}
40+
uses: ./.github/workflows/release-e2e-workflow-template.yml
41+
with:
42+
test-name: left navigation workspace disabled with security
43+
test-command: env CYPRESS_WORKSPACE_ENABLED=false CYPRESS_SAVED_OBJECTS_PERMISSION_ENABLED=true yarn cypress:run-with-security --browser chromium --spec 'cypress/integration/core-opensearch-dashboards/opensearch-dashboards/left-navigation/*'
44+
osd-serve-args: --workspace.enabled=false --savedObjects.permission.enabled=true --opensearch_security.multitenancy.enabled=false --opensearchDashboards.dashboardAdmin.users='["admin"]' --uiSettings.overrides.home:useNewHomePage=true
45+
artifact-name-suffix: '-workspace-disabled-with-security'
46+
tests-workspace-disabled-without-security:
47+
needs: changes
48+
if: ${{ needs.changes.outputs.tests == 'true' }}
49+
uses: ./.github/workflows/release-e2e-workflow-template.yml
50+
with:
51+
test-name: left navigation workspace disabled without security
52+
test-command: env CYPRESS_WORKSPACE_ENABLED=false yarn cypress:run-without-security --browser chromium --spec 'cypress/integration/core-opensearch-dashboards/opensearch-dashboards/left-navigation/*'
53+
osd-serve-args: --workspace.enabled=false --savedObjects.permission.enabled=false --uiSettings.overrides.home:useNewHomePage=true
54+
security-enabled: false
55+
artifact-name-suffix: '-workspace-disabled-without-security'
Lines changed: 315 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,315 @@
1+
/*
2+
* Copyright OpenSearch Contributors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
const isWorkspaceEnabled = Cypress.env('WORKSPACE_ENABLED');
7+
const workspaceName = `test_nav_menu`;
8+
const workspaceDescription =
9+
'This is a test workspace for left navigation menu.';
10+
let workspaceId;
11+
12+
const createWorkspace = (feature) => {
13+
return cy
14+
.createWorkspace({
15+
name: `${workspaceName}_${feature}`,
16+
description: workspaceDescription,
17+
features: [`use-case-${feature}`],
18+
})
19+
.then((value) => {
20+
workspaceId = value;
21+
return value;
22+
});
23+
};
24+
25+
if (isWorkspaceEnabled) {
26+
const validateWorkspaceNavMenu = (feature, callbackFn) => {
27+
createWorkspace(feature).then(() => {
28+
cy.visit(`w/${workspaceId}/app/discover`);
29+
// overview page should be loaded
30+
cy.get('.content').should('exist');
31+
32+
// navigation menu should be hidden initially
33+
cy.get('.navGroupEnabledNavTopWrapper').should('not.exist');
34+
35+
// top right navigation menu button should exist
36+
cy.get('.navToggleInLargeScreen').should('exist').click();
37+
38+
// navigation should be expanded and display content correctly
39+
cy.get('.left-navigation-wrapper').within(() => {
40+
cy.contains(`${workspaceName}_${feature}`).should('exist');
41+
cy.get('.navGroupEnabledHomeIcon').should('exist');
42+
cy.get('input[type="search"]').should('exist');
43+
cy.contains(/Manage workspace/).should('exist');
44+
45+
// additional assertion according to different type of workspace
46+
callbackFn();
47+
});
48+
});
49+
};
50+
51+
const validateWorkspaceNavMenuSearch = (input, callbackFn) => {
52+
createWorkspace('all').then(() => {
53+
cy.visit(`w/${workspaceId}/app/all_overview`);
54+
55+
// expand the navigation menu
56+
cy.get('.navToggleInLargeScreen').should('exist').click();
57+
58+
cy.get('input[type="search"]').should('exist').click();
59+
cy.get('input[type="search"]').type(input);
60+
61+
callbackFn();
62+
});
63+
};
64+
65+
describe('Left navigation menu in workspace', () => {
66+
before(() => {
67+
cy.deleteAllWorkspaces();
68+
});
69+
70+
afterEach(() => {
71+
if (workspaceId) {
72+
cy.deleteWorkspaceById(workspaceId);
73+
}
74+
});
75+
76+
it('features are visible inside left navigation for analytics use case', () => {
77+
validateWorkspaceNavMenu('all', () => {
78+
cy.contains(/Visualize and report/).should('exist');
79+
cy.contains(/Observability/).should('exist');
80+
cy.contains(/Security Analytics/).should('exist');
81+
cy.contains(/Search/).should('exist');
82+
cy.contains(/Detect/).should('exist');
83+
});
84+
});
85+
86+
it('features are visible inside left navigation for essentials use case', () => {
87+
validateWorkspaceNavMenu('essentials', () => {});
88+
});
89+
90+
it('features are visible inside left navigation for search use case', () => {
91+
validateWorkspaceNavMenu('search', () => {
92+
cy.contains(/Visualize and report/).should('exist');
93+
isWorkspaceEnabled &&
94+
cy.contains(/Compare search results/).should('exist');
95+
});
96+
});
97+
98+
it('features are visible inside left navigation for security analytics use case', () => {
99+
validateWorkspaceNavMenu('security-analytics', () => {
100+
cy.contains(/Visualize and report/).should('exist');
101+
cy.contains(/Threat detection/).should('exist');
102+
cy.contains(/Detect/).should('exist');
103+
cy.contains(/Alerting/).should('exist');
104+
cy.contains(/Anomaly Detection/).should('exist');
105+
});
106+
});
107+
108+
it('features are visible inside left navigation for observability use case', () => {
109+
validateWorkspaceNavMenu('observability', () => {
110+
cy.contains(/Visualize and report/).should('exist');
111+
cy.contains(/Detect/).should('exist');
112+
});
113+
});
114+
115+
it('verify workspace identification in navigation', () => {
116+
createWorkspace('all').then(() => {
117+
cy.visit(`w/${workspaceId}/app/all_overview`);
118+
// expand the navigation menu
119+
cy.get('.navToggleInLargeScreen').should('exist').click();
120+
cy.get('.bottom-container').within(() => {
121+
cy.get('div[id="workspaceDropdownMenu"]').should('exist').click();
122+
});
123+
124+
// expect workspace menu to be expanded with current workspace name displayed
125+
cy.get('.workspaceMenuHeader').within(() => {
126+
cy.contains(`${workspaceName}_all`).should('exist');
127+
});
128+
});
129+
});
130+
131+
it('navigation search should only search use case related features when inside a workspace', () => {
132+
validateWorkspaceNavMenuSearch('visu', () => {
133+
cy.getElementByTestId('search-result-panel').within(() => {
134+
cy.contains(/Visualizations/).should('exist');
135+
});
136+
});
137+
});
138+
139+
it('navigation search should show be able to search dev tools and open it as modal', () => {
140+
validateWorkspaceNavMenuSearch('dev', () => {
141+
cy.getElementByTestId('search-result-panel').within(() => {
142+
cy.contains(/Dev Tools/).should('exist');
143+
cy.contains(/Console/)
144+
.should('exist')
145+
.click();
146+
cy.document().then((doc) => {
147+
// click on the page to remove welcome message
148+
cy.wrap(doc.body).click('center');
149+
// expect dev tool popover to be opened
150+
cy.wrap(doc.body)
151+
.contains(/Dev Tools/)
152+
.should('exist');
153+
});
154+
});
155+
});
156+
});
157+
});
158+
}
159+
160+
describe('Left navigation menu', () => {
161+
before(() => {
162+
if (isWorkspaceEnabled) {
163+
cy.deleteAllWorkspaces();
164+
}
165+
});
166+
167+
afterEach(() => {
168+
if (isWorkspaceEnabled && workspaceId) {
169+
cy.deleteWorkspaceById(workspaceId);
170+
}
171+
});
172+
173+
it('collapsible menu sections', () => {
174+
const validateMenuSection = () => {
175+
// expand the navigation menu
176+
cy.get('.navToggleInLargeScreen').should('exist').click();
177+
178+
// menu section should be able to expand/collapse, with inside items display/hide corectly
179+
cy.contains(/Visualizations/).should('exist');
180+
181+
// collapse the menu section and expect content to be hidden
182+
cy.contains(/Visualize and report/)
183+
.should('exist')
184+
.click();
185+
cy.contains(/Visualizations/).should('not.exist');
186+
187+
// expand the menu section and expect content to be visible
188+
cy.contains(/Visualize and report/)
189+
.should('exist')
190+
.click();
191+
cy.contains(/Visualizations/).should('exist');
192+
};
193+
if (isWorkspaceEnabled) {
194+
createWorkspace('all').then(() => {
195+
cy.visit(`w/${workspaceId}/app/all_overview`);
196+
validateMenuSection();
197+
});
198+
} else {
199+
cy.visit('app/home');
200+
validateMenuSection();
201+
}
202+
});
203+
204+
it('navigation should remember state of expand in browser', () => {
205+
const validateMenuState = () => {
206+
cy.get('.navToggleInLargeScreen').should('exist').click(); // expand the menu
207+
208+
cy.reload();
209+
// navigation menu should remain expanded after reload
210+
cy.get('.left-navigation-wrapper').within(() => {
211+
isWorkspaceEnabled &&
212+
cy.contains(`${workspaceName}_all`).should('exist');
213+
cy.get('.navGroupEnabledHomeIcon').should('exist');
214+
cy.get('input[type="search"]').should('exist');
215+
cy.get('.bottom-container-expanded').should('exist');
216+
cy.getElementByTestId('collapsibleNavShrinkButton')
217+
.should('exist')
218+
.click(); // collapse the menu
219+
});
220+
221+
cy.reload();
222+
// navigation menu should remain collapsed after reload
223+
cy.get('.left-navigation-wrapper').find('.euiPanel').should('not.exist');
224+
cy.get('.left-navigation-wrapper').within(() => {
225+
isWorkspaceEnabled &&
226+
cy.contains(`${workspaceName}_all`).should('not.exist');
227+
cy.get('.navGroupEnabledHomeIcon').should('not.exist');
228+
cy.get('input[type="search"]').should('not.exist');
229+
cy.get('.bottom-container-expanded').should('not.exist');
230+
});
231+
};
232+
233+
if (isWorkspaceEnabled) {
234+
createWorkspace('all').then(() => {
235+
cy.visit(`w/${workspaceId}/app/all_overview`);
236+
validateMenuState();
237+
});
238+
} else {
239+
cy.visit('app/home');
240+
validateMenuState();
241+
}
242+
});
243+
244+
it('validate navigation history functionality', () => {
245+
const validateRecentHistory = () => {
246+
// expand the navigation menu
247+
cy.get('.navToggleInLargeScreen').should('exist').click();
248+
cy.contains(/Visualizations/)
249+
.should('exist')
250+
.click();
251+
252+
let visualizationName;
253+
cy.getElementByTestId('itemsInMemTable').within(() => {
254+
cy.get('.euiLink')
255+
.first()
256+
.invoke('text')
257+
.then((text) => {
258+
visualizationName = text;
259+
// Click to the first visualization item
260+
cy.contains(visualizationName).click();
261+
});
262+
});
263+
264+
// wait for the page to be loaded
265+
cy.get('.visualize').should('exist');
266+
cy.get('.headerRecentItemsButton--loadingIndicator').should('not.exist');
267+
268+
// open recent history dialog
269+
cy.get('.headerRecentItemsButton').should('exist').click();
270+
cy.get('div[role="dialog"]').within(() => {
271+
// dialog displays correct visited content
272+
cy.contains(/Recent assets/).should('exist');
273+
cy.contains(visualizationName).should('exist');
274+
});
275+
276+
// back to dashboard
277+
cy.get('.left-navigation-wrapper').within(() => {
278+
cy.contains(/Dashboards/)
279+
.should('exist')
280+
.click({ force: true });
281+
});
282+
283+
// wait for the page to be loaded
284+
cy.get('.application').should('exist');
285+
cy.get('.headerRecentItemsButton--loadingIndicator').should('not.exist');
286+
287+
// open recent history dialog again
288+
cy.get('.headerRecentItemsButton').should('exist').click();
289+
cy.get('div[role="dialog"]').within(() => {
290+
// click recent visited visualization in the dialog
291+
cy.contains(visualizationName).should('exist').click({ force: true });
292+
});
293+
294+
// should go back to the visualization screen just visited
295+
cy.getElementByTestId('headerAppActionMenu').within(() => {
296+
cy.url().should('contain', 'edit').should('contain', 'visualize');
297+
cy.contains(visualizationName).should('exist');
298+
});
299+
};
300+
301+
if (isWorkspaceEnabled) {
302+
createWorkspace('all').then(() => {
303+
cy.loadSampleDataForWorkspace('ecommerce', workspaceId).then(() => {
304+
cy.visit(`w/${workspaceId}/app/all_overview`);
305+
validateRecentHistory();
306+
});
307+
});
308+
} else {
309+
cy.loadSampleData('logs').then(() => {
310+
cy.visit('app/home');
311+
validateRecentHistory();
312+
});
313+
}
314+
});
315+
});

cypress/integration/plugins/observability-dashboards/3_trace_analytics_traces.spec.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
/// <reference types="cypress" />
77

88
import { setTimeFilter, TRACE_ID } from '../../../utils/constants';
9+
import customParseFormat from 'dayjs/plugin/customParseFormat';
10+
import dayjs from 'dayjs';
11+
12+
dayjs.extend(customParseFormat);
913

1014
describe('Testing traces table', () => {
1115
beforeEach(() => {

cypress/integration/plugins/observability-dashboards/6_notebooks.spec.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,10 @@ const deleteAllNotebooks = () => {
7373
'DELETE',
7474
'/api/observability/notebooks/note/savedNotebook/*'
7575
).as('deleteNotebook');
76-
77-
cy.wait(delayTime*3);
76+
77+
cy.wait(delayTime * 3);
7878
moveToNotebookHome();
79-
cy.wait(delayTime*3);
79+
cy.wait(delayTime * 3);
8080

8181
cy.get('[data-test-subj="globalLoadingIndicator"]').should('not.exist');
8282

0 commit comments

Comments
 (0)