Skip to content

Commit

Permalink
[Metrics UI] Add additional functional test for Inventory View (#116868
Browse files Browse the repository at this point in the history
…) (#118407)

* [Metrics UI] Add functional test for group by and sorting for Inventory View

* refactor groupByCustomField

* Adding search test

* Adding colors getNodesWithValues; adding test for changing palette;

* Adding basic test for timeline controls

* Closing the popover after clicking apply

Co-authored-by: Kibana Machine <[email protected]>

Co-authored-by: Chris Cowan <[email protected]>
  • Loading branch information
kibanamachine and simianhacker authored Nov 11, 2021
1 parent 706446f commit 7667ca4
Show file tree
Hide file tree
Showing 11 changed files with 190 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ export class AutocompleteField extends React.Component<
placeholder={placeholder}
value={value}
aria-label={ariaLabel}
data-test-subj="infraSearchField"
/>
{areSuggestionsVisible && !isLoadingSuggestions && suggestions.length > 0 ? (
<SuggestionsPanel>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export const BottomDrawer: React.FC<{
aria-expanded={isOpen}
iconType={isOpen ? 'arrowDown' : 'arrowRight'}
onClick={onClick}
data-test-subj="toggleTimelineButton"
>
{isOpen ? hideHistory : showHistory}
</ShowHideButton>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,9 @@ export const Timeline: React.FC<Props> = ({ interval, yAxisFormatter, isVisible
}

return (
<TimelineContainer>
<TimelineContainer
data-test-subj={isVisible ? 'timelineContainerOpen' : 'timelineContainerClosed'}
>
<TimelineHeader>
<EuiFlexItem grow={true}>
<EuiText>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export class CustomFieldPanel extends React.PureComponent<Props, State> {
fullWidth
>
<EuiComboBox
data-test-subj="groupByCustomField"
placeholder={i18n.translate('xpack.infra.waffle.customGroupByDropdownPlacehoder', {
defaultMessage: 'Select one',
})}
Expand All @@ -67,6 +68,7 @@ export class CustomFieldPanel extends React.PureComponent<Props, State> {
/>
</EuiFormRow>
<EuiButton
data-test-subj="groupByCustomFieldAddButton"
disabled={isSubmitDisabled}
type="submit"
size="s"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,11 @@ export class GroupName extends React.PureComponent<Props, {}> {
<Inner isChild={isChild}>
<Name>
<EuiToolTip position="top" content={group.name}>
<EuiLink style={linkStyle} onClickCapture={this.handleClick}>
<EuiLink
style={linkStyle}
onClickCapture={this.handleClick}
data-test-subj="groupNameLink"
>
{group.name}
</EuiLink>
</EuiToolTip>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ export const LegendControls = ({
defaultMessage: 'configure legend',
})}
onClick={() => setPopoverState(true)}
data-test-subj="openLegendControlsButton"
/>
);

Expand Down Expand Up @@ -131,6 +132,7 @@ export const LegendControls = ({
bounds: { min: draftBounds.min / 100, max: draftBounds.max / 100 },
legend: draftLegend,
});
setPopoverState(false);
}, [onChange, draftAuto, draftBounds, draftLegend]);

const handleCancelClick = useCallback(() => {
Expand Down Expand Up @@ -179,7 +181,7 @@ export const LegendControls = ({
: [];

return (
<ControlContainer>
<ControlContainer data-test-subj="legendControls">
<EuiPopover
isOpen={isPopoverOpen}
closePopover={handleCancelClick}
Expand All @@ -201,6 +203,7 @@ export const LegendControls = ({
id="palette"
onChange={handlePaletteChange}
compressed
data-test-subj="legendControlsPalette"
/>
<EuiSpacer size="m" />
<PalettePreview
Expand Down Expand Up @@ -338,6 +341,7 @@ export const LegendControls = ({
fill
disabled={commited || !boundsValidRange}
onClick={handleApplyClick}
data-test-subj="applyLegendControlsButton"
>
<FormattedMessage
id="xpack.infra.legendControls.applyButton"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,12 @@ export class Node extends React.PureComponent<Props, State> {
<SquareInner color={color}>
{valueMode ? (
<ValueInner aria-label={nodeAriaLabel}>
<Label color={color}>{node.name}</Label>
<Value color={color}>{value}</Value>
<Label data-test-subj="nodeName" color={color}>
{node.name}
</Label>
<Value data-test-subj="nodeValue" color={color}>
{value}
</Value>
</ValueInner>
) : (
ellipsisMode && (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ export class WaffleGroupByControls extends React.PureComponent<Props, State> {
<DropdownButton
label={i18n.translate('xpack.infra.waffle.groupByLabel', { defaultMessage: 'Group by' })}
onClick={this.handleToggle}
data-test-subj={'waffleGroupByDropdown'}
>
{buttonBody}
</DropdownButton>
Expand All @@ -147,7 +148,11 @@ export class WaffleGroupByControls extends React.PureComponent<Props, State> {
panelPaddingSize="none"
closePopover={this.handleClose}
>
<StyledContextMenu initialPanelId="firstPanel" panels={panels} />
<StyledContextMenu
initialPanelId="firstPanel"
panels={panels}
data-test-subj="groupByContextMenu"
/>
</EuiPopover>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export const WaffleSortControls = ({ sort, onChange }: Props) => {
<DropdownButton
label={i18n.translate('xpack.infra.waffle.sortLabel', { defaultMessage: 'Sort by' })}
onClick={showPopover}
data-test-subj={'waffleSortByDropdown'}
>
{label}
</DropdownButton>
Expand All @@ -59,7 +60,8 @@ export const WaffleSortControls = ({ sort, onChange }: Props) => {
...sort,
direction: sort.direction === 'asc' ? 'desc' : 'asc',
});
}, [sort, onChange]);
closePopover();
}, [closePopover, sort, onChange]);

const panels = useMemo<EuiContextMenuPanelDescriptor[]>(
() => [
Expand All @@ -71,11 +73,13 @@ export const WaffleSortControls = ({ sort, onChange }: Props) => {
name: LABELS.name,
icon: sort.by === 'name' ? 'check' : 'empty',
onClick: selectName,
'data-test-subj': 'waffleSortByName',
},
{
name: LABELS.value,
icon: sort.by === 'value' ? 'check' : 'empty',
onClick: selectValue,
'data-test-subj': 'waffleSortByValue',
},
],
},
Expand All @@ -101,6 +105,7 @@ export const WaffleSortControls = ({ sort, onChange }: Props) => {
})}
checked={sort.direction === 'desc'}
onChange={toggleSort}
data-test-subj={'waffleSortByDirection'}
/>
</SwitchContainer>
</EuiPopover>
Expand Down
78 changes: 75 additions & 3 deletions x-pack/test/functional/apps/infra/home_page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* 2.0.
*/

import expect from '@kbn/expect';
import { FtrProviderContext } from '../../ftr_provider_context';
import { DATES } from './constants';

Expand Down Expand Up @@ -44,15 +45,86 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
await esArchiver.unload('x-pack/test/functional/es_archives/infra/metrics_and_logs')
);

it('renders an empty data prompt for dates with no data', async () => {
await pageObjects.infraHome.goToTime(DATE_WITHOUT_DATA);
await pageObjects.infraHome.getNoMetricsDataPrompt();
});

it('renders the waffle map and tooltips for dates with data', async () => {
await pageObjects.infraHome.goToTime(DATE_WITH_DATA);
await pageObjects.infraHome.getWaffleMap();
await pageObjects.infraHome.getWaffleMapTooltips();
});

it('renders an empty data prompt for dates with no data', async () => {
await pageObjects.infraHome.goToTime(DATE_WITHOUT_DATA);
await pageObjects.infraHome.getNoMetricsDataPrompt();
it('sort nodes by descending value', async () => {
await pageObjects.infraHome.goToTime(DATE_WITH_DATA);
await pageObjects.infraHome.getWaffleMap();
await pageObjects.infraHome.sortNodesBy('value');
const nodesWithValue = await pageObjects.infraHome.getNodesWithValues();
expect(nodesWithValue).to.eql([
{ name: 'demo-stack-apache-01', value: 1.4, color: '#6092c0' },
{ name: 'demo-stack-mysql-01', value: 1.2, color: '#82a7cd' },
{ name: 'demo-stack-nginx-01', value: 1.1, color: '#93b1d3' },
{ name: 'demo-stack-redis-01', value: 1, color: '#a2bcd9' },
{ name: 'demo-stack-haproxy-01', value: 0.8, color: '#c2d2e6' },
{ name: 'demo-stack-client-01', value: 0.6, color: '#f0f4f9' },
]);
});

it('sort nodes by ascending value', async () => {
await pageObjects.infraHome.goToTime(DATE_WITH_DATA);
await pageObjects.infraHome.getWaffleMap();
await pageObjects.infraHome.sortNodesBy('value');
await pageObjects.infraHome.toggleReverseSort();
const nodesWithValue = await pageObjects.infraHome.getNodesWithValues();
expect(nodesWithValue).to.eql([
{ name: 'demo-stack-client-01', value: 0.6, color: '#f0f4f9' },
{ name: 'demo-stack-haproxy-01', value: 0.8, color: '#c2d2e6' },
{ name: 'demo-stack-redis-01', value: 1, color: '#a2bcd9' },
{ name: 'demo-stack-nginx-01', value: 1.1, color: '#93b1d3' },
{ name: 'demo-stack-mysql-01', value: 1.2, color: '#82a7cd' },
{ name: 'demo-stack-apache-01', value: 1.4, color: '#6092c0' },
]);
});

it('group nodes by custom field', async () => {
await pageObjects.infraHome.goToTime(DATE_WITH_DATA);
await pageObjects.infraHome.getWaffleMap();
const groups = await pageObjects.infraHome.groupByCustomField('host.os.platform');
expect(groups).to.eql(['ubuntu']);
});

it('filter nodes by search term', async () => {
await pageObjects.infraHome.goToTime(DATE_WITH_DATA);
await pageObjects.infraHome.getWaffleMap();
await pageObjects.infraHome.enterSearchTerm('host.name: "demo-stack-apache-01"');
const nodesWithValue = await pageObjects.infraHome.getNodesWithValues();
expect(nodesWithValue).to.eql([
{ name: 'demo-stack-apache-01', value: 1.4, color: '#6092c0' },
]);
await pageObjects.infraHome.clearSearchTerm();
});

it('change color palette', async () => {
await pageObjects.infraHome.openLegendControls();
await pageObjects.infraHome.changePalette('temperature');
await pageObjects.infraHome.applyLegendControls();
const nodesWithValue = await pageObjects.infraHome.getNodesWithValues();
expect(nodesWithValue).to.eql([
{ name: 'demo-stack-client-01', value: 0.6, color: '#6092c0' },
{ name: 'demo-stack-haproxy-01', value: 0.8, color: '#b5c9df' },
{ name: 'demo-stack-redis-01', value: 1, color: '#f1d9b9' },
{ name: 'demo-stack-nginx-01', value: 1.1, color: '#eec096' },
{ name: 'demo-stack-mysql-01', value: 1.2, color: '#eba47a' },
{ name: 'demo-stack-apache-01', value: 1.4, color: '#e7664c' },
]);
});

it('toggle the timeline', async () => {
await pageObjects.infraHome.goToTime(DATE_WITH_DATA);
await pageObjects.infraHome.getWaffleMap();
await pageObjects.infraHome.openTimeline();
await pageObjects.infraHome.closeTimeline();
});
});

Expand Down
80 changes: 80 additions & 0 deletions x-pack/test/functional/page_objects/infra_home_page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export function InfraHomePageProvider({ getService, getPageObjects }: FtrProvide
const find = getService('find');
const browser = getService('browser');
const pageObjects = getPageObjects(['common']);
const comboBox = getService('comboBox');

return {
async goToTime(time: string) {
Expand Down Expand Up @@ -65,6 +66,85 @@ export function InfraHomePageProvider({ getService, getPageObjects }: FtrProvide
expect(await values2[3].getVisibleText()).to.be('255.1kbit/s');
},

async getNodesWithValues() {
const nodes = await testSubjects.findAll('nodeContainer');
const promises = nodes.map(async (node) => {
const nodeName = await node.findByTestSubject('nodeName');
const name = await nodeName.getVisibleText();
const nodeValue = await node.findByTestSubject('nodeValue');
const value = await nodeValue.getVisibleText();
const color = await nodeValue.getAttribute('color');
return { name, value: parseFloat(value), color };
});
return await Promise.all(promises);
},

async sortNodesBy(sort: string) {
await testSubjects.click('waffleSortByDropdown');
if (sort === 'value') {
await testSubjects.find('waffleSortByValue');
await testSubjects.click('waffleSortByValue');
} else {
await testSubjects.find('waffleSortByName');
await testSubjects.click('waffleSortByName');
}
},

async groupByCustomField(field: string) {
await testSubjects.click('waffleGroupByDropdown');
const contextMenu = await testSubjects.find('groupByContextMenu');
const menuItems = await contextMenu.findAllByCssSelector('button.euiContextMenuItem');
await menuItems[0].click();
const groupByCustomField = await testSubjects.find('groupByCustomField');
await comboBox.setElement(groupByCustomField, field);
await testSubjects.click('groupByCustomFieldAddButton');
await this.waitForLoading();
const groupNameLinks = await testSubjects.findAll('groupNameLink');
return Promise.all(groupNameLinks.map(async (link) => link.getVisibleText()));
},

async enterSearchTerm(query: string) {
const input = await this.clearSearchTerm();
await input.type([query, browser.keys.RETURN]);
await this.waitForLoading();
},

async clearSearchTerm() {
const input = await testSubjects.find('infraSearchField');
await input.clearValueWithKeyboard({ charByChar: true });
return input;
},

async openLegendControls() {
await testSubjects.click('openLegendControlsButton');
await testSubjects.find('legendControls');
},

async changePalette(paletteId: string) {
await testSubjects.find('legendControlsPalette');
await testSubjects.selectValue('legendControlsPalette', paletteId);
},

async applyLegendControls() {
await testSubjects.click('applyLegendControlsButton');
},

async toggleReverseSort() {
await testSubjects.click('waffleSortByDropdown');
await testSubjects.find('waffleSortByDirection');
await testSubjects.click('waffleSortByDirection');
},

async openTimeline() {
await testSubjects.click('toggleTimelineButton');
await testSubjects.existOrFail('timelineContainerOpen');
},

async closeTimeline() {
await testSubjects.click('toggleTimelineButton');
await testSubjects.existOrFail('timelineContainerClosed');
},

async openInvenotrySwitcher() {
await testSubjects.click('openInventorySwitcher');
return await testSubjects.find('goToHost');
Expand Down

0 comments on commit 7667ca4

Please sign in to comment.