mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[Discover] Add focus to h1 on navigate for single document and surrounding document views (#134942)
[Discover] Add focus to h1 on navigate for single document and surrounding document views
This commit is contained in:
parent
158e4f693d
commit
d12db42360
8 changed files with 162 additions and 1 deletions
|
@ -15,6 +15,7 @@ import { cloneDeep } from 'lodash';
|
|||
import { DataView, DataViewField } from '@kbn/data-views-plugin/public';
|
||||
import { useExecutionContext } from '@kbn/kibana-react-plugin/public';
|
||||
import { generateFilters } from '@kbn/data-plugin/public';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { DOC_TABLE_LEGACY, SEARCH_FIELDS_FROM_SOURCE } from '../../../common';
|
||||
import { ContextErrorMessage } from './components/context_error_message';
|
||||
import { LoadingStatus } from './services/context_query_state';
|
||||
|
@ -143,12 +144,29 @@ export const ContextApp = ({ indexPattern, anchorId }: ContextAppProps) => {
|
|||
};
|
||||
};
|
||||
|
||||
const contextAppTitle = useRef<HTMLHeadingElement>(null);
|
||||
useEffect(() => {
|
||||
contextAppTitle.current?.focus();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
{fetchedState.anchorStatus.value === LoadingStatus.FAILED ? (
|
||||
<ContextErrorMessage status={fetchedState.anchorStatus} />
|
||||
) : (
|
||||
<Fragment>
|
||||
<h1
|
||||
id="contextAppTitle"
|
||||
className="euiScreenReaderOnly"
|
||||
data-test-subj="discoverContextAppTitle"
|
||||
tabIndex={-1}
|
||||
ref={contextAppTitle}
|
||||
>
|
||||
{i18n.translate('discover.context.pageTitle', {
|
||||
defaultMessage: 'Documents surrounding #{anchorId}',
|
||||
values: { anchorId },
|
||||
})}
|
||||
</h1>
|
||||
<TopNavMenu {...getNavBarProps()} />
|
||||
<EuiPage className={classNames({ dscDocsPage: !isLegacy })}>
|
||||
<EuiPageContent paddingSize="s" className="dscDocsContent">
|
||||
|
|
|
@ -6,10 +6,11 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import React, { useEffect, useRef } from 'react';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { EuiCallOut, EuiLink, EuiLoadingSpinner, EuiPageContent, EuiPage } from '@elastic/eui';
|
||||
import type { DataView } from '@kbn/data-views-plugin/public';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { DocViewer } from '../../../services/doc_views/components/doc_viewer';
|
||||
import { ElasticRequestState } from '../types';
|
||||
import { useEsDocSearch } from '../../../hooks/use_es_doc_search';
|
||||
|
@ -39,8 +40,26 @@ export function Doc(props: DocProps) {
|
|||
const [reqState, hit] = useEsDocSearch(props);
|
||||
const { docLinks } = useDiscoverServices();
|
||||
const indexExistsLink = docLinks.links.apis.indexExists;
|
||||
|
||||
const singleDocTitle = useRef<HTMLHeadingElement>(null);
|
||||
useEffect(() => {
|
||||
singleDocTitle.current?.focus();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<EuiPage>
|
||||
<h1
|
||||
id="singleDocTitle"
|
||||
className="euiScreenReaderOnly"
|
||||
data-test-subj="discoverSingleDocTitle"
|
||||
tabIndex={-1}
|
||||
ref={singleDocTitle}
|
||||
>
|
||||
{i18n.translate('discover.doc.pageTitle', {
|
||||
defaultMessage: 'Single document - #{id}',
|
||||
values: { id: props.id },
|
||||
})}
|
||||
</h1>
|
||||
<EuiPageContent>
|
||||
{reqState === ElasticRequestState.NotFoundIndexPattern && (
|
||||
<EuiCallOut
|
||||
|
|
|
@ -21,6 +21,7 @@ exports[`Render <DocViewer/> with 3 different tabs 1`] = `
|
|||
}
|
||||
title="Render function"
|
||||
/>,
|
||||
"data-test-subj": "docViewerTab-0",
|
||||
"id": "kbn_doc_viewer_tab_0",
|
||||
"name": "Render function",
|
||||
},
|
||||
|
@ -35,6 +36,7 @@ exports[`Render <DocViewer/> with 3 different tabs 1`] = `
|
|||
}
|
||||
title="React component"
|
||||
/>,
|
||||
"data-test-subj": "docViewerTab-1",
|
||||
"id": "kbn_doc_viewer_tab_1",
|
||||
"name": "React component",
|
||||
},
|
||||
|
@ -48,6 +50,7 @@ exports[`Render <DocViewer/> with 3 different tabs 1`] = `
|
|||
}
|
||||
title="Invalid doc view"
|
||||
/>,
|
||||
"data-test-subj": "docViewerTab-2",
|
||||
"id": "kbn_doc_viewer_tab_2",
|
||||
"name": "Invalid doc view",
|
||||
},
|
||||
|
|
|
@ -35,6 +35,7 @@ export function DocViewer(renderProps: DocViewRenderProps) {
|
|||
render={render}
|
||||
/>
|
||||
),
|
||||
['data-test-subj']: `docViewerTab-${idx}`,
|
||||
};
|
||||
});
|
||||
|
||||
|
|
55
test/functional/apps/context/_context_accessibility.ts
Normal file
55
test/functional/apps/context/_context_accessibility.ts
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* 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 kibanaServer = getService('kibanaServer');
|
||||
const find = getService('find');
|
||||
const testSubjects = getService('testSubjects');
|
||||
const dataGrid = getService('dataGrid');
|
||||
const PageObjects = getPageObjects(['common', 'discover', 'header', 'timePicker', 'context']);
|
||||
|
||||
describe('context accessibility', () => {
|
||||
before(async () => {
|
||||
await PageObjects.timePicker.setDefaultAbsoluteRangeViaUiSettings();
|
||||
await kibanaServer.uiSettings.update({
|
||||
defaultIndex: 'logstash-*',
|
||||
});
|
||||
await PageObjects.common.navigateToApp('discover');
|
||||
await PageObjects.header.waitUntilLoadingHasFinished();
|
||||
});
|
||||
|
||||
after(async function () {
|
||||
await kibanaServer.uiSettings.replace({});
|
||||
});
|
||||
|
||||
it('should navigate to the single doc view and give focus to the title h1 on navigate', async () => {
|
||||
await dataGrid.clickRowToggle({ rowIndex: 0 });
|
||||
const rowActions = await dataGrid.getRowActions({ rowIndex: 0 });
|
||||
await rowActions[1].click();
|
||||
const titleElement = await testSubjects.find('discoverContextAppTitle');
|
||||
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 table tab link when Tab is pressed', async () => {
|
||||
await browser.pressKeys(browser.keys.TAB);
|
||||
const dataViewSwitchLink = await testSubjects.find('showQueryBarMenu');
|
||||
const activeElement = await find.activeElement();
|
||||
expect(await dataViewSwitchLink.getAttribute('data-test-subj')).to.eql(
|
||||
await activeElement.getAttribute('data-test-subj')
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
|
@ -29,6 +29,7 @@ export default function ({ getService, getPageObjects, loadTestFile }: FtrProvid
|
|||
);
|
||||
});
|
||||
|
||||
loadTestFile(require.resolve('./_context_accessibility'));
|
||||
loadTestFile(require.resolve('./_context_navigation'));
|
||||
loadTestFile(require.resolve('./_discover_navigation'));
|
||||
loadTestFile(require.resolve('./classic/_discover_navigation'));
|
||||
|
|
63
test/functional/apps/discover/_doc_accessibility.ts
Normal file
63
test/functional/apps/discover/_doc_accessibility.ts
Normal file
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* 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 dataGrid = getService('dataGrid');
|
||||
const PageObjects = getPageObjects(['common', 'discover', 'header', 'timePicker', 'context']);
|
||||
|
||||
const defaultSettings = {
|
||||
defaultIndex: 'logstash-*',
|
||||
};
|
||||
|
||||
describe('discover doc 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.timePicker.setDefaultAbsoluteRangeViaUiSettings();
|
||||
await PageObjects.common.navigateToApp('discover');
|
||||
await PageObjects.header.waitUntilLoadingHasFinished();
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await kibanaServer.savedObjects.clean({ types: ['search', 'index-pattern'] });
|
||||
});
|
||||
|
||||
it('should navigate to the single doc view and give focus to the title h1 on navigate', async () => {
|
||||
await dataGrid.clickRowToggle({ rowIndex: 0 });
|
||||
const rowActions = await dataGrid.getRowActions({ rowIndex: 0 });
|
||||
await rowActions[0].click();
|
||||
const titleElement = await testSubjects.find('discoverSingleDocTitle');
|
||||
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 first tab link when Tab is pressed', async () => {
|
||||
await browser.pressKeys(browser.keys.TAB);
|
||||
const tableTab = await testSubjects.find('docViewerTab-0');
|
||||
const activeElement = await find.activeElement();
|
||||
expect(await tableTab.getAttribute('data-test-subj')).to.eql(
|
||||
await activeElement.getAttribute('data-test-subj')
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
|
@ -30,6 +30,7 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) {
|
|||
loadTestFile(require.resolve('./_discover'));
|
||||
loadTestFile(require.resolve('./_discover_accessibility'));
|
||||
loadTestFile(require.resolve('./_discover_histogram'));
|
||||
loadTestFile(require.resolve('./_doc_accessibility'));
|
||||
loadTestFile(require.resolve('./classic/_doc_table'));
|
||||
loadTestFile(require.resolve('./classic/_doc_table_newline'));
|
||||
loadTestFile(require.resolve('./_filter_editor'));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue