From 523ecd76b5f8429d7c703486c5931a17d266b3c3 Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Fri, 8 May 2020 09:56:58 -0400 Subject: [PATCH 1/7] [Uptime] Add `a11y` tests (#65514) * Add test attributes and missing aria labels to uptime UI code. * Add uptime a11y tests and associated helper functions. * Append a11y test instructions to uptime README. * Update some copy on README page. Refresh outdated snapshot. * Add test for alert popover on overview page. Co-authored-by: Elastic Machine --- x-pack/plugins/uptime/README.md | 16 ++++ .../__snapshots__/monitor_list.test.tsx.snap | 2 + .../overview/monitor_list/monitor_list.tsx | 1 + .../actions_popover/actions_popover.tsx | 1 + .../components/settings/certificate_form.tsx | 3 + .../components/settings/translations.ts | 24 ++++++ x-pack/test/accessibility/apps/uptime.ts | 86 +++++++++++++++++++ x-pack/test/accessibility/config.ts | 1 + .../functional/services/uptime/overview.ts | 34 ++++++++ .../test/functional/services/uptime/uptime.ts | 3 + 10 files changed, 171 insertions(+) create mode 100644 x-pack/plugins/uptime/public/components/settings/translations.ts create mode 100644 x-pack/test/accessibility/apps/uptime.ts create mode 100644 x-pack/test/functional/services/uptime/overview.ts diff --git a/x-pack/plugins/uptime/README.md b/x-pack/plugins/uptime/README.md index 92162341ff4266..10c1fc0edcd00d 100644 --- a/x-pack/plugins/uptime/README.md +++ b/x-pack/plugins/uptime/README.md @@ -75,3 +75,19 @@ We can run these tests like described above, but with some special config. `node scripts/functional_tests_server.js --config=test/functional_with_es_ssl/config.ts` `node scripts/functional_test_runner.js --config=test/functional_with_es_ssl/config.ts` + +#### Running accessibility tests + +We maintain a suite of Accessibility tests (you may see them referred to elsewhere as `a11y` tests). + +These tests render each of our pages and ensure that the inputs and other elements contain the +attributes necessary to ensure all users are able to make use of Kibana (for example, users relying +on screen readers). + +The commands for running these tests are very similar to the other functional tests described above. + +From the `~/x-pack` directory: + +Start the server: `node scripts/functional_tests_server --config test/accessibility/config.ts` + +Run the uptime `a11y` tests: `node scripts/functional_test_runner.js --config test/accessibility/config.ts --grep=uptime` diff --git a/x-pack/plugins/uptime/public/components/overview/monitor_list/__tests__/__snapshots__/monitor_list.test.tsx.snap b/x-pack/plugins/uptime/public/components/overview/monitor_list/__tests__/__snapshots__/monitor_list.test.tsx.snap index 7772b886f7a4f9..727cf2518549d3 100644 --- a/x-pack/plugins/uptime/public/components/overview/monitor_list/__tests__/__snapshots__/monitor_list.test.tsx.snap +++ b/x-pack/plugins/uptime/public/components/overview/monitor_list/__tests__/__snapshots__/monitor_list.test.tsx.snap @@ -953,6 +953,7 @@ exports[`MonitorList component renders the monitor list 1`] = ` -
- {{(hits || 0) | number:0}} - - -
+ +
; + + beforeAll(() => { + props = { + onResetQuery: jest.fn(), + showResetButton: true, + hits: 2, + }; + }); + + it('HitsCounter renders a button by providing the showResetButton property', () => { + component = mountWithIntl(); + expect(findTestSubject(component, 'resetSavedSearch').length).toBe(1); + }); + + it('HitsCounter not renders a button when the showResetButton property is false', () => { + component = mountWithIntl( + + ); + expect(findTestSubject(component, 'resetSavedSearch').length).toBe(0); + }); + + it('expect to render the number of hits', function() { + component = mountWithIntl(); + const hits = findTestSubject(component, 'discoverQueryHits'); + expect(hits.text()).toBe('2'); + }); + + it('expect to render 1,899 hits if 1899 hits given', function() { + component = mountWithIntl( + + ); + const hits = findTestSubject(component, 'discoverQueryHits'); + expect(hits.text()).toBe('1,899'); + }); + + it('should reset query', function() { + component = mountWithIntl(); + findTestSubject(component, 'resetSavedSearch').simulate('click'); + expect(props.onResetQuery).toHaveBeenCalled(); + }); +}); diff --git a/src/plugins/discover/public/application/components/hits_counter/hits_counter.tsx b/src/plugins/discover/public/application/components/hits_counter/hits_counter.tsx new file mode 100644 index 00000000000000..1d2cd12877b1c0 --- /dev/null +++ b/src/plugins/discover/public/application/components/hits_counter/hits_counter.tsx @@ -0,0 +1,83 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import React from 'react'; +import { EuiButtonEmpty, EuiFlexGroup, EuiFlexItem, EuiText } from '@elastic/eui'; +import { FormattedMessage, I18nProvider } from '@kbn/i18n/react'; +import { i18n } from '@kbn/i18n'; +import { formatNumWithCommas } from '../../helpers'; + +export interface HitsCounterProps { + /** + * the number of query hits + */ + hits: number; + /** + * displays the reset button + */ + showResetButton: boolean; + /** + * resets the query + */ + onResetQuery: () => void; +} + +export function HitsCounter({ hits, showResetButton, onResetQuery }: HitsCounterProps) { + return ( + + + + + {formatNumWithCommas(hits)}{' '} + + + + {showResetButton && ( + + + + + + )} + + + ); +} diff --git a/src/plugins/discover/public/application/components/hits_counter/hits_counter_directive.ts b/src/plugins/discover/public/application/components/hits_counter/hits_counter_directive.ts new file mode 100644 index 00000000000000..8d45e28370cade --- /dev/null +++ b/src/plugins/discover/public/application/components/hits_counter/hits_counter_directive.ts @@ -0,0 +1,27 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import { HitsCounter } from './hits_counter'; + +export function createHitsCounterDirective(reactDirective: any) { + return reactDirective(HitsCounter, [ + ['hits', { watchDepth: 'reference' }], + ['showResetButton', { watchDepth: 'reference' }], + ['onResetQuery', { watchDepth: 'reference' }], + ]); +} diff --git a/src/plugins/discover/public/application/components/hits_counter/index.ts b/src/plugins/discover/public/application/components/hits_counter/index.ts new file mode 100644 index 00000000000000..58e7a9eda7f51a --- /dev/null +++ b/src/plugins/discover/public/application/components/hits_counter/index.ts @@ -0,0 +1,21 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export { HitsCounter } from './hits_counter'; +export { createHitsCounterDirective } from './hits_counter_directive'; diff --git a/src/plugins/discover/public/application/helpers/format_number_with_commas.ts b/src/plugins/discover/public/application/helpers/format_number_with_commas.ts new file mode 100644 index 00000000000000..01a010d823d5f3 --- /dev/null +++ b/src/plugins/discover/public/application/helpers/format_number_with_commas.ts @@ -0,0 +1,27 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +const COMMA_SEPARATOR_RE = /(\d)(?=(\d{3})+(?!\d))/g; + +/** + * Converts a number to a string and adds commas + * as thousands separators + */ +export const formatNumWithCommas = (input: number) => + String(input).replace(COMMA_SEPARATOR_RE, '$1,'); diff --git a/src/plugins/discover/public/application/helpers/index.ts b/src/plugins/discover/public/application/helpers/index.ts index 7196c96989e97d..3555d24924e806 100644 --- a/src/plugins/discover/public/application/helpers/index.ts +++ b/src/plugins/discover/public/application/helpers/index.ts @@ -18,3 +18,4 @@ */ export { shortenDottedString } from './shorten_dotted_string'; +export { formatNumWithCommas } from './format_number_with_commas'; diff --git a/src/plugins/discover/public/get_inner_angular.ts b/src/plugins/discover/public/get_inner_angular.ts index e7813c43383f93..8c3f4f030688ce 100644 --- a/src/plugins/discover/public/get_inner_angular.ts +++ b/src/plugins/discover/public/get_inner_angular.ts @@ -57,6 +57,7 @@ import { createTopNavHelper, } from '../../kibana_legacy/public'; import { createDiscoverSidebarDirective } from './application/components/sidebar'; +import { createHitsCounterDirective } from '././application/components/hits_counter'; import { DiscoverStartPlugins } from './plugin'; /** @@ -151,6 +152,7 @@ export function initializeInnerAngularModule( .directive('fixedScroll', FixedScrollProvider) .directive('renderComplete', createRenderCompleteDirective) .directive('discoverSidebar', createDiscoverSidebarDirective) + .directive('hitsCounter', createHitsCounterDirective) .service('debounce', ['$timeout', DebounceProviderTimeout]); } From d40387161e16aa9cf8396d669c1f8478ec674442 Mon Sep 17 00:00:00 2001 From: Brian Seeders Date: Fri, 8 May 2020 11:35:17 -0400 Subject: [PATCH 5/7] Skipping failing tests. #65867 #65866 #65865 --- .../server/models/job_validation/job_validation.test.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/ml/server/models/job_validation/job_validation.test.ts b/x-pack/plugins/ml/server/models/job_validation/job_validation.test.ts index 9851f80a42d5bb..ca127f43d08afe 100644 --- a/x-pack/plugins/ml/server/models/job_validation/job_validation.test.ts +++ b/x-pack/plugins/ml/server/models/job_validation/job_validation.test.ts @@ -290,7 +290,8 @@ describe('ML - validateJob', () => { }); }); - it('basic validation passes, extended checks return some messages', () => { + // Failing https://github.com/elastic/kibana/issues/65865 + it.skip('basic validation passes, extended checks return some messages', () => { const payload = getBasicPayload(); return validateJob(callWithRequest, payload).then(messages => { const ids = messages.map(m => m.id); @@ -303,7 +304,8 @@ describe('ML - validateJob', () => { }); }); - it('categorization job using mlcategory passes aggregatable field check', () => { + // Failing https://github.com/elastic/kibana/issues/65866 + it.skip('categorization job using mlcategory passes aggregatable field check', () => { const payload: any = { job: { job_id: 'categorization_test', @@ -369,7 +371,8 @@ describe('ML - validateJob', () => { }); }); - it('script field not reported as non aggregatable', () => { + // Failing https://github.com/elastic/kibana/issues/65867 + it.skip('script field not reported as non aggregatable', () => { const payload: any = { job: { job_id: 'categorization_test', From e79f331fb460c954dcb2d8fcf5704681f26d9f5a Mon Sep 17 00:00:00 2001 From: Andrew Goldstein Date: Fri, 8 May 2020 09:38:38 -0600 Subject: [PATCH 6/7] [SIEM] Fixes a CSS issue with Timeline field truncation (#65789) ## Summary Fixes [a CSS issue where Timeline field truncation](https://github.com/elastic/kibana/issues/65170) wasn't working, per the following screenshots: ### Before before ### After after ## Desk testing * The timeline in the _Before_ and _After_ screenshots above includes columns that typically contain large values (e.g. `process.hash.sha256`). It also contains the `event.module` column, which has special formatting, as detailed below. * You may re-create the timeline shown in the _Before_ and _After_ screenshots, or download the exported timeline from the following link [truncation.ndjson.txt](https://github.com/elastic/kibana/files/4596036/truncation.ndjson.txt) and import it. (Remove the `.txt` extension after downloading it.) * The `event.module` field has special formatting that displays an icon link to the endpoint if it's been configured. To desk test this without configuring an endpoint, edit `x-pack/plugins/siem/public/components/timeline/body/renderers/formatted_field_helpers.tsx`, and change the following line: ``` {endpointRefUrl != null && canYouAddEndpointLogo(moduleName, endpointRefUrl) && ( ``` to ``` {true && ( ``` The above change forces the icon to always appear, even if you don't have an endpoint configured. ### Desk tested in: - Chrome `81.0.4044.138` - Firefox `76.0` - Safari `13.1` --- .../body/renderers/formatted_field_helpers.tsx | 9 +++++++-- .../public/components/with_hover_actions/index.tsx | 13 +++++++++++-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/siem/public/components/timeline/body/renderers/formatted_field_helpers.tsx b/x-pack/plugins/siem/public/components/timeline/body/renderers/formatted_field_helpers.tsx index b48cc546fe78cf..7c9accd4cef49e 100644 --- a/x-pack/plugins/siem/public/components/timeline/body/renderers/formatted_field_helpers.tsx +++ b/x-pack/plugins/siem/public/components/timeline/body/renderers/formatted_field_helpers.tsx @@ -7,6 +7,7 @@ import { EuiLink, EuiFlexGroup, EuiFlexItem, EuiIcon, EuiToolTip } from '@elastic/eui'; import { isString, isEmpty } from 'lodash/fp'; import React from 'react'; +import styled from 'styled-components'; import { DefaultDraggable } from '../../../draggables'; import { getEmptyTagValue } from '../../../empty_value'; @@ -18,6 +19,10 @@ import endPointSvg from '../../../../utils/logo_endpoint/64_color.svg'; import * as i18n from './translations'; +const EventModuleFlexItem = styled(EuiFlexItem)` + width: 100%; +`; + export const renderRuleName = ({ contextId, eventId, @@ -87,7 +92,7 @@ export const renderEventModule = ({ endpointRefUrl != null && !isEmpty(endpointRefUrl) ? 'flexStart' : 'spaceBetween' } > - + {content} - + {endpointRefUrl != null && canYouAddEndpointLogo(moduleName, endpointRefUrl) && ( ( const popover = useMemo(() => { return ( - ( panelPaddingSize={!alwaysShow ? 's' : 'none'} > {isOpen ? hoverContent : null} - + ); }, [content, onMouseLeave, isOpen, alwaysShow, hoverContent]); From 3a6c1ceeddfb51efed5cff163599ab17bcf78701 Mon Sep 17 00:00:00 2001 From: Matthias Wilhelm Date: Fri, 8 May 2020 17:56:28 +0200 Subject: [PATCH 7/7] [Discover] Prevent whitespace wrapping of doc table header (#52861) Co-authored-by: Dave Snider --- .../angular/doc_table/components/_table_header.scss | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/plugins/discover/public/application/angular/doc_table/components/_table_header.scss b/src/plugins/discover/public/application/angular/doc_table/components/_table_header.scss index 099286f8c875c6..9ea4e21632ace9 100644 --- a/src/plugins/discover/public/application/angular/doc_table/components/_table_header.scss +++ b/src/plugins/discover/public/application/angular/doc_table/components/_table_header.scss @@ -1,3 +1,6 @@ +.kbnDocTableHeader { + white-space: nowrap; +} .kbnDocTableHeader button { margin-left: $euiSizeXS; }