Skip to content

Commit

Permalink
restore desc for process icons. fix tests
Browse files Browse the repository at this point in the history
  • Loading branch information
oatkiller committed Aug 10, 2020
1 parent d8800d9 commit 9e5cef0
Show file tree
Hide file tree
Showing 7 changed files with 113 additions and 98 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -219,31 +219,17 @@ export class Simulator {
}

/**
* An element with a list of all nodes.
* The titles of the links that select a node in the node list view.
*/
public nodeListElement(): ReactWrapper {
return this.domNodes('[data-test-subj="resolver:node-list"]');
public nodeListNodeLinkText(): ReactWrapper {
return this.domNodes('[data-test-subj="resolver:node-list:node-link:title"]');
}

/**
* Return the items in the node list (the default panel view.)
* The icons in the links that select a node in the node list view.
*/
public nodeListItems(): ReactWrapper {
return this.domNodes('[data-test-subj="resolver:node-list:item"]');
}

/**
* The links that select a node in the node list view.
*/
public nodeListNodeLinks(): ReactWrapper {
return this.domNodes('[data-test-subj="resolver:node-list:node-link"]');
}

/**
* The element containing the details for the selected node.
*/
public nodeDetailElement(): ReactWrapper {
return this.domNodes('[data-test-subj="resolver:node-detail"]');
public nodeListNodeLinkIcons(): ReactWrapper {
return this.domNodes('[data-test-subj="resolver:node-list:node-link:icon"]');
}

/**
Expand All @@ -261,17 +247,10 @@ export class Simulator {
}

/**
* The details of the selected node are shown in a description list. This returns the title elements of the description list.
* The icon element for the node detail title.
*/
private nodeDetailEntryTitle(): ReactWrapper {
return this.domNodes('[data-test-subj="resolver:node-detail:entry-title"]');
}

/**
* The details of the selected node are shown in a description list. This returns the description elements of the description list.
*/
private nodeDetailEntryDescription(): ReactWrapper {
return this.domNodes('[data-test-subj="resolver:node-detail:entry-description"]');
public nodeDetailViewTitleIcon(): ReactWrapper {
return this.domNodes('[data-test-subj="resolver:node-detail:title-icon"]');
}

/**
Expand All @@ -287,8 +266,14 @@ export class Simulator {
* The titles and descriptions (as text) from the node detail panel.
*/
public nodeDetailDescriptionListEntries(): Array<[string, string]> {
const titles = this.nodeDetailEntryTitle();
const descriptions = this.nodeDetailEntryDescription();
/**
* The details of the selected node are shown in a description list. This returns the title elements of the description list.
*/
const titles = this.domNodes('[data-test-subj="resolver:node-detail:entry-title"]');
/**
* The details of the selected node are shown in a description list. This returns the description elements of the description list.
*/
const descriptions = this.domNodes('[data-test-subj="resolver:node-detail:entry-description"]');
const entries: Array<[string, string]> = [];
for (let index = 0; index < Math.min(titles.length, descriptions.length); index++) {
const title = titles.at(index).text();
Expand Down
14 changes: 5 additions & 9 deletions x-pack/plugins/security_solution/public/resolver/view/assets.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@
* you may not use this file except in compliance with the Elastic License.
*/

/* eslint-disable react/display-name */

import React, { memo } from 'react';
import euiThemeAmsterdamDark from '@elastic/eui/dist/eui_theme_amsterdam_dark.json';
import euiThemeAmsterdamLight from '@elastic/eui/dist/eui_theme_amsterdam_light.json';
import { htmlIdGenerator, ButtonColor } from '@elastic/eui';
import styled from 'styled-components';
import { i18n } from '@kbn/i18n';
import { useUiSetting } from '../../common/lib/kibana';
import { DEFAULT_DARK_MODE } from '../../../common/constants';
import { DEFAULT_DARK_MODE as defaultDarkMode } from '../../../common/constants';
import { ResolverProcessType } from '../types';

type ResolverColorNames =
Expand Down Expand Up @@ -141,8 +143,6 @@ const PaintServers = memo(({ isDarkMode }: { isDarkMode: boolean }) => (
</>
));

PaintServers.displayName = 'PaintServers';

/**
* Ids of symbols to be linked by <use> elements
*/
Expand Down Expand Up @@ -376,8 +376,6 @@ const SymbolsAndShapes = memo(({ isDarkMode }: { isDarkMode: boolean }) => (
</>
));

SymbolsAndShapes.displayName = 'SymbolsAndShapes';

/**
* This `<defs>` element is used to define the reusable assets for the Resolver
* It confers several advantages, including but not limited to:
Expand All @@ -386,7 +384,7 @@ SymbolsAndShapes.displayName = 'SymbolsAndShapes';
* 3. `<use>` elements can be handled by compositor (faster)
*/
const SymbolDefinitionsComponent = memo(({ className }: { className?: string }) => {
const isDarkMode = useUiSetting<boolean>(DEFAULT_DARK_MODE);
const isDarkMode = useUiSetting<boolean>(defaultDarkMode);
return (
<svg className={className}>
<defs>
Expand All @@ -397,8 +395,6 @@ const SymbolDefinitionsComponent = memo(({ className }: { className?: string })
);
});

SymbolDefinitionsComponent.displayName = 'SymbolDefinitions';

export const SymbolDefinitions = styled(SymbolDefinitionsComponent)`
position: absolute;
left: 100%;
Expand All @@ -424,7 +420,7 @@ export const useResolverTheme = (): {
nodeAssets: NodeStyleMap;
cubeAssetsForNode: (isProcessTerimnated: boolean, isProcessTrigger: boolean) => NodeStyleConfig;
} => {
const isDarkMode = useUiSetting<boolean>(DEFAULT_DARK_MODE);
const isDarkMode = useUiSetting<boolean>(defaultDarkMode);
const theme = isDarkMode ? euiThemeAmsterdamDark : euiThemeAmsterdamLight;

const getThemedOption = (lightOption: string, darkOption: string): string => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,9 @@ describe('Resolver, when analyzing a tree that has no ancestors and 2 children',
});
});

it(`should show the node list`, async () => {
await expect(simulator.map(() => simulator.nodeListElement().length)).toYieldEqualTo(1);
it(`should show links to the 3 nodes (with icons) in the node list.`, async () => {
await expect(simulator.map(() => simulator.nodeListNodeLinkText().length)).toYieldEqualTo(3);
await expect(simulator.map(() => simulator.nodeListNodeLinkIcons().length)).toYieldEqualTo(3);
});

describe("when the second child node's first button has been clicked", () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,16 +71,28 @@ describe(`Resolver: when analyzing a tree with no ancestors and two children, an
});
it('should show the node details for the origin', async () => {
await expect(
simulator().map(() => simulator().nodeDetailDescriptionListEntries())
).toYieldEqualTo([
['process.executable', 'executable'],
['process.pid', '0'],
['user.name', 'user.name'],
['user.domain', 'user.domain'],
['process.parent.pid', '0'],
['process.hash.md5', 'hash.md5'],
['process.args', 'args'],
]);
simulator().map(() => {
const titleWrapper = simulator().nodeDetailViewTitle();
const titleIconWrapper = simulator().nodeDetailViewTitleIcon();
return {
title: titleWrapper.exists() ? titleWrapper.text() : null,
titleIcon: titleIconWrapper.exists() ? titleIconWrapper.text() : null,
detailEntries: simulator().nodeDetailDescriptionListEntries(),
};
})
).toYieldEqualTo({
title: 'c',
titleIcon: 'Running Process',
detailEntries: [
['process.executable', 'executable'],
['process.pid', '0'],
['user.name', 'user.name'],
['user.domain', 'user.domain'],
['process.parent.pid', '0'],
['process.hash.md5', 'hash.md5'],
['process.args', 'args'],
],
});
});
});

Expand Down Expand Up @@ -109,19 +121,21 @@ describe(`Resolver: when analyzing a tree with no ancestors and two children, an
});
});

it('should show the node list', async () => {
await expect(simulator().map(() => simulator().nodeListElement().length)).toYieldEqualTo(1);
it('should have 3 nodes (with icons) in the node list', async () => {
await expect(simulator().map(() => simulator().nodeListNodeLinkText().length)).toYieldEqualTo(
3
);
await expect(simulator().map(() => simulator().nodeListNodeLinkIcons().length)).toYieldEqualTo(
3
);
});

it('should have 3 nodes in the node list', async () => {
await expect(simulator().map(() => simulator().nodeListItems().length)).toYieldEqualTo(3);
});
describe('when there is an item in the node list and it has been clicked', () => {
describe('when there is an item in the node list and its text has been clicked', () => {
beforeEach(async () => {
const nodeListItems = await simulator().resolveWrapper(() => simulator().nodeListItems());
expect(nodeListItems && nodeListItems.length).toBeTruthy();
if (nodeListItems) {
nodeListItems.first().find('button').simulate('click');
const nodeLinks = await simulator().resolveWrapper(() => simulator().nodeListNodeLinkText());
expect(nodeLinks).toBeTruthy();
if (nodeLinks) {
nodeLinks.first().simulate('click');
}
});
it('should show the details for the first node', async () => {
Expand Down Expand Up @@ -155,7 +169,7 @@ describe(`Resolver: when analyzing a tree with no ancestors and two children, an
await expect(
simulator().map(() => {
return simulator()
.nodeListNodeLinks()
.nodeListNodeLinkText()
.map((node) => node.text());
})
).toYieldEqualTo(['c', 'd', 'e']);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,41 +4,55 @@
* you may not use this file except in compliance with the Elastic License.
*/

import styled from 'styled-components';

import { i18n } from '@kbn/i18n';

/* eslint-disable react/display-name */

import React, { memo } from 'react';
import { useResolverTheme } from '../assets';

/**
* During user testing, one user indicated they wanted to see stronger visual relationships between
* Nodes on the graph and what's in the table. Using the same symbol in both places (as below) could help with that.
* Icon representing a process node.
*/
export const CubeForProcess = memo(function CubeForProcess({
isProcessTerminated,
export const CubeForProcess = memo(function ({
running,
'data-test-subj': dataTestSubj,
}: {
isProcessTerminated: boolean;
'data-test-subj'?: string;
/**
* True if the process represented by the node is still running.
*/
running: boolean;
}) {
const { cubeAssetsForNode } = useResolverTheme();
const { cubeSymbol } = cubeAssetsForNode(isProcessTerminated, false);
const { cubeSymbol } = cubeAssetsForNode(!running, false);

return (
<>
<svg
style={{ position: 'relative', top: '0.4em', marginRight: '.25em' }}
className="table-process-icon"
width="1.5em"
height="1.5em"
viewBox="0 0 1 1"
>
<use
role="presentation"
xlinkHref={cubeSymbol}
x={0}
y={0}
width={1}
height={1}
opacity="1"
className="cube"
/>
</svg>
</>
<StyledSVG width="1.5em" height="1.5em" viewBox="0 0 1 1" data-test-subj={dataTestSubj}>
<desc>
{i18n.translate('xpack.securitySolution.resolver.node_icon', {
defaultMessage: '{running, select, true {Running Process} false {Terminated Process}}',
values: { running },
})}
</desc>
<use
role="presentation"
xlinkHref={cubeSymbol}
x={0}
y={0}
width={1}
height={1}
opacity="1"
className="cube"
/>
</StyledSVG>
);
});

const StyledSVG = styled.svg`
position: relative;
top: 0.4em;
margin-right: 0.25em;
`;
Original file line number Diff line number Diff line change
Expand Up @@ -156,20 +156,23 @@ export const ProcessDetails = memo(function ProcessDetails({
return cubeAssetsForNode(isProcessTerminated, false);
}, [processEvent, cubeAssetsForNode, isProcessTerminated]);

const titleId = useMemo(() => htmlIdGenerator('resolverTable')(), []);
const titleID = useMemo(() => htmlIdGenerator('resolverTable')(), []);
return (
<>
<StyledBreadcrumbs breadcrumbs={crumbs} />
<EuiSpacer size="l" />
<EuiTitle size="xs">
<h4 data-test-subj="resolver:node-detail:title" aria-describedby={titleId}>
<CubeForProcess isProcessTerminated={isProcessTerminated} />
{processName}
<h4 aria-describedby={titleID}>
<CubeForProcess
data-test-subj="resolver:node-detail:title-icon"
running={!isProcessTerminated}
/>
<span data-test-subj="resolver:node-detail:title">{processName}</span>
</h4>
</EuiTitle>
<EuiText>
<EuiTextColor color="subdued">
<span id={titleId}>{descriptionText}</span>
<span id={titleID}>{descriptionText}</span>
</EuiTextColor>
</EuiText>
<EuiSpacer size="l" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,10 +110,12 @@ export const ProcessListWithCounts = memo(function ProcessListWithCounts({
crumbEvent: '',
});
}}
data-test-subj="resolver:node-list:node-link"
>
<CubeForProcess isProcessTerminated={isTerminated} />
{name}
<CubeForProcess
running={!isTerminated}
data-test-subj="resolver:node-list:node-link:icon"
/>
<span data-test-subj="resolver:node-list:node-link:title">{name}</span>
</EuiButtonEmpty>
);
},
Expand Down

0 comments on commit 9e5cef0

Please sign in to comment.