Skip to content

Commit

Permalink
[Cypress Updates] App analytics updates (#2261) (#2276)
Browse files Browse the repository at this point in the history
* update cypress testing for app analytics

Signed-off-by: Ritvi Bhatt <[email protected]>

* replace wait

Signed-off-by: Ritvi Bhatt <[email protected]>

* change action menu for metrics

Signed-off-by: Ritvi Bhatt <[email protected]>

* update snapshots

Signed-off-by: Ritvi Bhatt <[email protected]>

* wait for service entities and trace groups to load

Signed-off-by: Ritvi Bhatt <[email protected]>

* load deleted applications

Signed-off-by: Ritvi Bhatt <[email protected]>

* remove deleted applications from table without reload

Signed-off-by: Ritvi Bhatt <[email protected]>

* fix deleting saved visualizations

Signed-off-by: Ritvi Bhatt <[email protected]>

* type in applications to delete

Signed-off-by: Ritvi Bhatt <[email protected]>

---------

Signed-off-by: Ritvi Bhatt <[email protected]>
Co-authored-by: Ritvi Bhatt <[email protected]>
(cherry picked from commit 9c94bc9)

Co-authored-by: Adam Tackett <[email protected]>
  • Loading branch information
ritvibhatt and TackAdam authored Dec 6, 2024
1 parent 3af9dd8 commit ce19b4e
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 46 deletions.
54 changes: 25 additions & 29 deletions .cypress/integration/app_analytics_test/app_analytics.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ describe('Setting availability', () => {
cy.get('.euiTableRow').should('have.length.lessThan', 1);
cy.get('[data-test-subj="applicationTitle"]').should('contain', nameThree);
cy.get('.euiBreadcrumb[href="#/"]').click();
cy.reload();
cy.get(`[data-test-subj="${nameThree}ApplicationLink"]`);
cy.get('[data-test-subj="setAvailabilityHomePageLink"]').first().click();
cy.get('[data-test-subj="applicationTitle"]').should('contain', nameThree);
Expand Down Expand Up @@ -254,13 +255,15 @@ describe('Viewing application', () => {

it('Shows latency variance in dashboards table', () => {
changeTimeTo24('years');
cy.get('[data-test-subj="app-analytics-traceTab"]').click();
cy.get('[data-test-subj="trace-groups-service-operation-accordian"]').click();
cy.get('[data-test-subj="dashboardTable"]').first().within(($table) => {
cy.get('.plot-container').should('have.length.at.least', 1);
})
});

it('Adds filter when Trace group name is clicked', () => {
cy.get('[data-test-subj="app-analytics-traceTab"]').click();
cy.get('[data-test-subj="trace-groups-service-operation-accordian"]').click();
cy.get('[data-test-subj="dashboard-table-trace-group-name-button"]').contains('client_create_order').click();
cy.get('[data-test-subj="client_create_orderFilterBadge"]').should('exist');
Expand All @@ -271,7 +274,7 @@ describe('Viewing application', () => {

it('Opens service detail flyout when Service Name is clicked', () => {
cy.get('[data-test-subj="app-analytics-serviceTab"]').click();
cy.get('.euiLink').contains('authentication').click();
cy.get('*[data-test-subj^="service-flyout-action-btntrace"]').eq(0).click();
cy.get('[data-test-subj="serviceDetailFlyoutTitle"]').should('be.visible');
cy.get('[data-test-subj="Number of connected servicesDescriptionList"]').should('contain', '3');
cy.get('[data-text="Errors"]').eq(1).click(); // Selecting errors tab within flyout
Expand Down Expand Up @@ -432,11 +435,12 @@ describe('Viewing application', () => {
cy.get('[data-test-subj="app-analytics-configTab"]').click();
cy.get('select').select(visOneName);
cy.intercept('PUT', `**/api/observability/application`).as('selectUpdate');
cy.wait('@selectUpdate')
cy.wait(2000); // despite the previous wait grabbing the call that updates the panel select, it doesn't appear without this
cy.wait('@selectUpdate');

moveToHomePage();
cy.intercept('GET', `**/api/observability/operational_panels/panels/**`).as('loadingPanels')
cy.wait('@loadingPanels');
cy.reload();
cy.get('[data-test-subj="AvailableAvailabilityBadge"][style="background-color: rgb(84, 179, 153); color: rgb(0, 0, 0);"]').should('contain', 'Available');
moveToApplication(nameOne);
cy.get('[data-test-subj="app-analytics-configTab"]').click();
Expand Down Expand Up @@ -479,8 +483,7 @@ describe('Separate from other plugins', () => {
cy.visit(
`${Cypress.env('opensearchDashboards')}/app/observability-dashboards#/`
);
cy.get('[data-test-subj="operationalPanelsActionsButton"]', { timeout: timeoutDelay }).click();
cy.get('[data-test-subj="addSampleContextMenuItem"]', { timeout: timeoutDelay }).click();
cy.get('.euiButtonContent').contains('Add samples').click();
cy.get('[data-test-subj="confirmModalConfirmButton"]', { timeout: timeoutDelay }).click();
cy.get('.euiLink').contains('[Logs] Web traffic Panel').first().click();
cy.get('[data-test-subj="addVisualizationButton"]').click();
Expand Down Expand Up @@ -517,10 +520,12 @@ describe('Editing application', () => {
cy.get('[data-test-subj="logSourceAccordion"]').trigger('mouseover').click();
cy.get('[data-test-subj="searchAutocompleteTextArea"]').should('be.disabled');
cy.get('[data-test-subj="servicesEntitiesAccordion"]').trigger('mouseover').click();
cy.get('[data-test-subj="servicesEntitiesCountBadge"]').should('contain', '1');
cy.get('[data-test-subj="servicesEntitiesComboBox"]').click();
cy.get('.euiFilterSelectItem').contains(service_two).click();
cy.get('[data-test-subj="servicesEntitiesCountBadge"]').should('contain', '2');
cy.get('[data-test-subj="traceGroupsAccordion"]').trigger('mouseover').click();
cy.get('[data-test-subj="traceGroupsCountBadge"]').should('contain', '2');
cy.get('[data-test-subj="comboBoxToggleListButton"]').eq(1).click();
cy.get('.euiFilterSelectItem').contains(trace_three).trigger('click');
cy.get('[data-test-subj="traceGroupsCountBadge"]').should('contain', '3');
Expand All @@ -547,39 +552,30 @@ describe('Application Analytics home page', () => {
});

it('Renames application', () => {
cy.get('[data-test-subj="appAnalyticsActionsButton"]').click();
cy.get('[data-test-subj="renameApplicationContextMenuItem"]').should('be.disabled');
cy.get('[data-test-subj="appAnalyticsActionsButton"]').click();
cy.get('.euiTableRow').first().find('.euiCheckbox').click();
cy.wait(2000); // checkbox being clicked has a small delay before enabling action button
cy.get('[data-test-subj="appAnalyticsActionsButton"]').click();
cy.get('[data-test-subj="renameApplicationContextMenuItem"]').click();
cy.get('[data-test-subj="customModalFieldText"]').clear().click().type(newName);
cy.get('[data-test-subj="runModalButton"]').click();
cy.get('[data-test-subj="renameApplication"]').eq(0).click();
cy.get('input[type="text"]').clear().click().type(newName);
cy.get('.euiButton__text').contains('Rename').click();
cy.get('.euiToast').contains(`Application successfully renamed to "${newName}"`);
cy.get('.euiTableRow').first().within(($row) => {
cy.get('.euiLink').contains(newName).should('exist');
});
});

it('Deletes application', () => {
cy.get('[data-test-subj="appAnalyticsActionsButton"]').click();
cy.get('[data-test-subj="deleteApplicationContextMenuItem"]').should('exist');
cy.get('[data-test-subj="appAnalyticsActionsButton"]').click();
cy.get('.euiTableRow').first().within(($row) => {
cy.get('.euiCheckbox').click();
});
cy.get('.euiTableRow').eq(1).within(($row) => {
cy.get('.euiCheckbox').click();
});
cy.get('.euiTableRow').eq(2).within(($row) => {
cy.get('.euiCheckbox').click();
});
cy.get('[data-test-subj="appAnalyticsActionsButton"]').click();
cy.get('[data-test-subj="deleteApplicationContextMenuItem"]').click();
cy.get('.euiFieldSearch').clear().type(nameTwo);
cy.get('[data-test-subj="deleteApplication"]').click();
cy.get('[data-test-subj="popoverModal__deleteTextInput"]').type('delete');
cy.get('[data-test-subj="popoverModal__deleteButton"').click();
cy.get('.euiToast').contains(`Applications successfully deleted!`);
cy.get(`[data-test-subj="${newName}ApplicationLink"]`).should('not.exist');
cy.get('.euiFieldSearch').clear().type(nameThree);
cy.get('[data-test-subj="deleteApplication"]').click();
cy.get('[data-test-subj="popoverModal__deleteTextInput"]').type('delete');
cy.get('[data-test-subj="popoverModal__deleteButton"').click();
cy.get('.euiFieldSearch').clear().type(newName);
cy.get('[data-test-subj="deleteApplication"]').click();
cy.get('[data-test-subj="popoverModal__deleteTextInput"]').type('delete');
cy.get('[data-test-subj="popoverModal__deleteButton"').click();
cy.get('.euiFieldSearch').clear()
cy.get('[data-test-subj="applicationHomePageTitle"]').contains('(0)');
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ export function AppTable(props: AppTableProps) {
);
clear();
fetchApplications();
}, [applications.length]);
}, []);

const clear = () => {
setFilters([]);
Expand Down Expand Up @@ -138,6 +138,7 @@ export function AppTable(props: AppTableProps) {
description: 'Rename this application',
icon: 'pencil',
type: 'icon',
'data-test-subj': 'renameApplication',
onClick: (app: ApplicationType) => renameApp(app),
},
{
Expand All @@ -146,6 +147,7 @@ export function AppTable(props: AppTableProps) {
icon: 'trash',
type: 'icon',
color: 'danger',
'data-test-subj': 'deleteApplication',
onClick: (app: ApplicationType) => deleteApp(app),
},
];
Expand Down Expand Up @@ -231,7 +233,7 @@ export function AppTable(props: AppTableProps) {
<EuiPageBody component="div">
<EuiPageHeader>
{!newNavigation && (
<EuiTitle size="l">
<EuiTitle data-test-subj="applicationHomePageTitle" size="l">
<h3>Applications {` (${applications.length})`}</h3>
</EuiTitle>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ export function Application(props: AppDetailProps) {
<ServicesContent
{...props}
page="app"
nameColumnAction={nameColumnAction}
setCurrentSelectedService={nameColumnAction}
traceColumnAction={traceColumnAction}
parentBreadcrumb={parentBreadcrumbs[0]}
childBreadcrumbs={childBreadcrumbs}
Expand Down
19 changes: 9 additions & 10 deletions public/components/application_analytics/home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import {
isNameValid,
removeTabData,
} from './helpers/utils';
import { SavedObjectsActions } from '../../services/saved_objects/saved_object_client/saved_objects_actions';

export type AppAnalyticsCoreDeps = TraceAnalyticsCoreDeps;

Expand Down Expand Up @@ -201,9 +202,8 @@ export const Home = (props: HomeProps) => {
const deleteSavedVisualizationsForPanel = async (appPanelId: string) => {
const savedVizIdsToDelete = await fetchPanelsVizIdList(http, appPanelId);
if (!isEmpty(savedVizIdsToDelete)) {
savedObjects
.deleteSavedObjectsList({ objectIdList: savedVizIdsToDelete })
.then((res) => {
await SavedObjectsActions.deleteBulk({ objectIdList: savedVizIdsToDelete })
.then((_res) => {
deletePanelForApp(appPanelId);
})
.catch((err) => {
Expand Down Expand Up @@ -350,14 +350,10 @@ export const Home = (props: HomeProps) => {
};

// Delete existing applications
const deleteApp = (appList: string[], panelList: string[], toastMessage?: string) => {
const deleteApp = async (appList: string[], panelList: string[], toastMessage?: string) => {
return http
.delete(`${APP_ANALYTICS_API_PREFIX}/${appList.join(',')}`)
.then((res) => {
setApplicationList((prevApplicationList) => {
return prevApplicationList.filter((app) => !appList.includes(app.id));
});

.delete(`${APP_ANALYTICS_API_PREFIX}/${[...appList].join(',')}`)
.then(async (res) => {
for (let i = 0; i < appList.length; i++) {
removeTabData(dispatch, appList[i], '');
}
Expand All @@ -366,6 +362,9 @@ export const Home = (props: HomeProps) => {
deleteSavedVisualizationsForPanel(panelList[i]);
}

setApplicationList((prevApplicationList) => {
return prevApplicationList.filter((app) => !appList.includes(app.id));
});
const message =
toastMessage || `Application${appList.length > 1 ? 's' : ''} successfully deleted!`;
setToast(message);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,48 @@ exports[`Visualization Container Component renders add visualization container 1
</EuiText>
</div>
</EuiFlexItem>
<EuiFlexItem
className="visualization-action-button"
grow={false}
>
<div
className="euiFlexItem euiFlexItem--flexGrowZero visualization-action-button"
>
<EuiIcon
data-test-subj="removeVisualizationButton"
onClick={[Function]}
type="crossInACircleFilled"
>
<EuiIconBeaker
aria-hidden={true}
className="euiIcon euiIcon--medium euiIcon-isLoading"
data-test-subj="removeVisualizationButton"
focusable="false"
onClick={[Function]}
role="img"
style={null}
>
<svg
aria-hidden={true}
className="euiIcon euiIcon--medium euiIcon-isLoading"
data-test-subj="removeVisualizationButton"
focusable="false"
height={16}
onClick={[Function]}
role="img"
style={null}
viewBox="0 0 16 16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M5.277 10.088c.02.014.04.03.057.047.582.55 1.134.812 1.666.812.586 0 1.84-.293 3.713-.88L9 6.212V2H7v4.212l-1.723 3.876Zm-.438.987L3.539 14h8.922l-1.32-2.969C9.096 11.677 7.733 12 7 12c-.74 0-1.463-.315-2.161-.925ZM6 2H5V1h6v1h-1v4l3.375 7.594A1 1 0 0 1 12.461 15H3.54a1 1 0 0 1-.914-1.406L6 6V2Z"
/>
</svg>
</EuiIconBeaker>
</EuiIcon>
</div>
</EuiFlexItem>
</div>
</EuiFlexGroup>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@
import {
EuiButton,
EuiSmallButton,
EuiSmallButtonIcon,
EuiCodeBlock,
EuiContextMenuItem,
EuiContextMenuPanel,
EuiFlexGroup,
EuiFlexItem,
EuiIcon,
Expand All @@ -18,6 +20,7 @@ import {
EuiModalHeader,
EuiModalHeaderTitle,
EuiPanel,
EuiPopover,
EuiSpacer,
EuiText,
EuiToolTip,
Expand Down Expand Up @@ -101,6 +104,7 @@ export const VisualizationContainer = ({
onEditClick,
cloneVisualization,
showFlyout,
removeVisualization,
catalogVisualization,
inlineEditor,
actionMenuType,
Expand All @@ -113,6 +117,7 @@ export const VisualizationContainer = ({
const [visualizationData, setVisualizationData] = useState<Plotly.Data[]>([]);
const [isLoading, setIsLoading] = useState(true);
const [isError, setIsError] = useState({} as VizContainerError);
const onActionsMenuClick = () => setIsPopoverOpen((currPopoverOpen) => !currPopoverOpen);
const closeActionsMenu = () => setIsPopoverOpen(false);
const { http, pplService } = coreRefs;
const { setToast } = useToast();
Expand Down Expand Up @@ -234,10 +239,7 @@ export const VisualizationContainer = ({
</EuiContextMenuItem>,
];

if (
visualizationMetaData?.metricType === PROMQL_METRIC_SUBTYPE &&
actionMenuType === 'metricsGrid'
) {
if (actionMenuType === 'metricsGrid') {
popoverPanel = [showPPLQueryPanel];
} else if (usedInNotebooks) {
popoverPanel = [popoverPanel[0]];
Expand Down Expand Up @@ -369,6 +371,37 @@ export const VisualizationContainer = ({
</EuiToolTip>
</EuiText>
</EuiFlexItem>
<EuiFlexItem grow={false} className="visualization-action-button">
{editMode ? (
<EuiIcon
data-test-subj="removeVisualizationButton"
type="crossInACircleFilled"
onClick={() => {
removeVisualization(visualizationId);
}}
/>
) : (
<EuiPopover
button={
<EuiSmallButtonIcon
aria-label="actionMenuButton"
iconType="boxesHorizontal"
onClick={onActionsMenuClick}
/>
}
isOpen={isPopoverOpen}
closePopover={closeActionsMenu}
anchorPosition="downLeft"
panelPaddingSize="none"
>
<EuiContextMenuPanel
items={popoverPanel}
data-test-subj="panelViz__popoverPanel"
size="s"
/>
</EuiPopover>
)}
</EuiFlexItem>
</EuiFlexGroup>
{inlineEditor}
</div>
Expand Down

0 comments on commit ce19b4e

Please sign in to comment.