[Discover] Added focus to h1 element when client side routing is executed (#133846)

* [Discover] Added focus to h1 element on navigate

* [Discover] Moved Discover h1 to above the nav bar, and added functional tests for Discover accessibility

* [Discover] Moved Discover accessibility functional tests to their own file
This commit is contained in:
Davis McPhee 2022-06-15 09:58:38 -03:00 committed by GitHub
parent 89ab1083a4
commit adb61f74eb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 99 additions and 14 deletions

View file

@ -39,7 +39,11 @@ import { DiscoverServices } from '../../../../build_services';
setHeaderActionMenuMounter(jest.fn());
function mountComponent(indexPattern: DataView, prevSidebarClosed?: boolean) {
function mountComponent(
indexPattern: DataView,
prevSidebarClosed?: boolean,
mountOptions: { attachTo?: HTMLElement } = {}
) {
const searchSourceMock = createSearchSourceMock({});
const services = {
...discoverServiceMock,
@ -159,7 +163,8 @@ function mountComponent(indexPattern: DataView, prevSidebarClosed?: boolean) {
return mountWithIntl(
<KibanaContextProvider services={services}>
<DiscoverLayout {...(props as DiscoverLayoutProps)} />
</KibanaContextProvider>
</KibanaContextProvider>,
mountOptions
);
}
@ -174,6 +179,17 @@ describe('Discover component', () => {
expect(component.find('[data-test-subj="discoverChartOptionsToggle"]').exists()).toBeTruthy();
});
test('the saved search title h1 gains focus on navigate', () => {
const container = document.createElement('div');
document.body.appendChild(container);
const component = mountComponent(indexPatternWithTimefieldMock, undefined, {
attachTo: container,
});
expect(
component.find('[data-test-subj="discoverSavedSearchTitle"]').getDOMNode()
).toHaveFocus();
});
describe('sidebar', () => {
test('should be opened if discover:sidebarClosed was not set', () => {
const component = mountComponent(indexPatternWithTimefieldMock, undefined);

View file

@ -213,8 +213,31 @@ export function DiscoverLayout({
[onChangeIndexPattern]
);
const savedSearchTitle = useRef<HTMLHeadingElement>(null);
useEffect(() => {
savedSearchTitle.current?.focus();
}, []);
return (
<EuiPage className="dscPage" data-fetch-counter={fetchCounter.current}>
<h1
id="savedSearchTitle"
className="euiScreenReaderOnly"
data-test-subj="discoverSavedSearchTitle"
tabIndex={-1}
ref={savedSearchTitle}
>
{savedSearch.title
? i18n.translate('discover.pageTitleWithSavedSearch', {
defaultMessage: 'Discover - {savedSearchTitle}',
values: {
savedSearchTitle: savedSearch.title,
},
})
: i18n.translate('discover.pageTitleWithoutSavedSearch', {
defaultMessage: 'Discover - Search not yet saved',
})}
</h1>
<TopNavMemoized
indexPattern={indexPattern}
onOpenInspector={onOpenInspector}
@ -236,18 +259,6 @@ export function DiscoverLayout({
spaces={spaces}
history={history}
/>
<h1 id="savedSearchTitle" className="euiScreenReaderOnly">
{savedSearch.title
? i18n.translate('discover.pageTitleWithSavedSearch', {
defaultMessage: 'Discover - {savedSearchTitle}',
values: {
savedSearchTitle: savedSearch.title,
},
})
: i18n.translate('discover.pageTitleWithoutSavedSearch', {
defaultMessage: 'Discover - Search not yet saved',
})}
</h1>
<EuiFlexGroup className="dscPageBody__contents" gutterSize="s">
<EuiFlexItem grow={false}>
<SidebarMemoized

View file

@ -0,0 +1,57 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import expect from '@kbn/expect';
import { FtrProviderContext } from '../../ftr_provider_context';
export default function ({ getService, getPageObjects }: FtrProviderContext) {
const browser = getService('browser');
const log = getService('log');
const esArchiver = getService('esArchiver');
const kibanaServer = getService('kibanaServer');
const find = getService('find');
const testSubjects = getService('testSubjects');
const PageObjects = getPageObjects(['common', 'discover', 'header', 'timePicker']);
const defaultSettings = {
defaultIndex: 'logstash-*',
};
describe('discover accessibility', () => {
before(async () => {
log.debug('load kibana index with default index pattern');
await kibanaServer.importExport.load('test/functional/fixtures/kbn_archiver/discover');
// and load a set of makelogs data
await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/logstash_functional');
await kibanaServer.uiSettings.replace(defaultSettings);
await PageObjects.common.navigateToApp('discover');
});
after(async () => {
await kibanaServer.savedObjects.clean({ types: ['search', 'index-pattern'] });
});
it('should give focus to the saved search title h1 on navigate', async () => {
const titleElement = await testSubjects.find('discoverSavedSearchTitle');
const activeElement = await find.activeElement();
expect(await titleElement.getAttribute('data-test-subj')).to.eql(
await activeElement.getAttribute('data-test-subj')
);
});
it('should give focus to the data view switch link when Tab is pressed', async () => {
await browser.pressKeys(browser.keys.TAB);
const dataViewSwitchLink = await testSubjects.find('discover-dataView-switch-link');
const activeElement = await find.activeElement();
expect(await dataViewSwitchLink.getAttribute('data-test-subj')).to.eql(
await activeElement.getAttribute('data-test-subj')
);
});
});
}

View file

@ -28,6 +28,7 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) {
loadTestFile(require.resolve('./_no_data'));
loadTestFile(require.resolve('./_saved_queries'));
loadTestFile(require.resolve('./_discover'));
loadTestFile(require.resolve('./_discover_accessibility'));
loadTestFile(require.resolve('./_discover_histogram'));
loadTestFile(require.resolve('./_doc_table'));
loadTestFile(require.resolve('./_doc_table_newline'));