[Serverless Search] Add telemetry linting (#171757)

## Summary

This adds linting for presence of `data-test-subj` on interactable
elements.
This commit is contained in:
Sander Philipse 2023-11-23 10:38:26 +01:00 committed by GitHub
parent 14bec21d8d
commit 4ea8eaf138
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 119 additions and 20 deletions

View file

@ -1539,6 +1539,17 @@ module.exports = {
},
},
/**
* Serverless Search overrides
*/
{
// All files
files: ['x-pack/plugins/serverless_search/**/*.{ts,tsx}', 'packages/kbn-search-*'],
rules: {
'@kbn/telemetry/event_generating_elements_should_be_instrumented': 'error',
},
},
/**
* Canvas overrides
*/

View file

@ -72,7 +72,13 @@ export const BasicSetupForm: React.FC<BasicSetupFormProps> = ({
defaultMessage: 'User',
})}
>
<EuiFieldText fullWidth disabled={true} value={user} onChange={() => {}} />
<EuiFieldText
data-test-subj="serverlessSearchBasicSetupFormFieldText"
fullWidth
disabled={true}
value={user}
onChange={() => {}}
/>
</EuiFormRow>
<EuiFormRow
fullWidth

View file

@ -24,7 +24,11 @@ export const MetadataForm: React.FC<MetadataFormProps> = ({
}) => {
return (
<div data-test-subj="create-api-metadata-code-editor-container">
<EuiLink href={docLinks.metadata} target="_blank">
<EuiLink
data-test-subj="serverlessSearchMetadataFormLearnHowToStructureRoleMetadataLink"
href={docLinks.metadata}
target="_blank"
>
{i18n.translate('xpack.serverlessSearch.apiKey.metadataLinkLabel', {
defaultMessage: 'Learn how to structure role metadata',
})}

View file

@ -24,7 +24,11 @@ export const SecurityPrivilegesForm: React.FC<SecurityPrivilegesFormProps> = ({
}) => {
return (
<div data-test-subj="create-api-role-descriptors-code-editor-container">
<EuiLink href={docLinks.roleDescriptors} target="_blank">
<EuiLink
data-test-subj="serverlessSearchSecurityPrivilegesFormLearnHowToStructureRoleDescriptorsLink"
href={docLinks.roleDescriptors}
target="_blank"
>
{i18n.translate('xpack.serverlessSearch.apiKey.roleDescriptorsLinkLabel', {
defaultMessage: 'Learn how to structure role descriptors',
})}

View file

@ -58,6 +58,7 @@ export const ApiKeyPanel: React.FC<ApiKeyPanelProps> = ({ connector }) => {
<EuiSpacer />
<span>
<EuiButton
data-test-subj="serverlessSearchApiKeyPanelNewApiKeyButton"
isDisabled={!connector.index_name}
isLoading={isLoading}
iconType="plusInCircle"

View file

@ -92,6 +92,7 @@ export const ConnectorIndexName: React.FC<ConnectorIndexNameProps> = ({ connecto
<EuiFlexItem grow={false}>
<span>
<EuiButton
data-test-subj="serverlessSearchConnectorIndexNameButton"
color="primary"
isDisabled={!isValidIndexName(newIndexName)}
isLoading={isLoading}
@ -104,6 +105,7 @@ export const ConnectorIndexName: React.FC<ConnectorIndexNameProps> = ({ connecto
<EuiFlexItem grow={false}>
<span>
<EuiButton
data-test-subj="serverlessSearchConnectorIndexNameSaveAndSyncButton"
color="primary"
disabled={
!(

View file

@ -68,6 +68,7 @@ export const ConnectorIndexnamePanel: React.FC<ConnectorIndexNamePanelProps> = (
<EuiFlexItem>
<span>
<EuiButton
data-test-subj="serverlessSearchConnectorIndexnamePanelButton"
color="primary"
disabled={!isValidIndexName(newIndexName)}
fill

View file

@ -17,6 +17,7 @@ import {
EuiTitle,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
import { ELASTICSEARCH_URL_PLACEHOLDER } from '@kbn/search-api-panels/constants';
import { ConnectorStatus } from '@kbn/search-connectors';
import React from 'react';
@ -63,7 +64,12 @@ export const ConnectorLinkElasticsearch: React.FC<ConnectorLinkElasticsearchProp
<EuiFlexGroup direction="row" alignItems="center" justifyContent="center">
<EuiFlexItem grow={false}>
<span>
<EuiButton iconType={`${assetBasePath}/docker.svg`} href={docLinks.connectors} fill>
<EuiButton
data-test-subj="serverlessSearchConnectorLinkElasticsearchRunWithDockerButton"
iconType={`${assetBasePath}/docker.svg`}
href={docLinks.connectors}
fill
>
{i18n.translate('xpack.serverlessSearch.connectors.runWithDockerLink', {
defaultMessage: 'Run with Docker',
})}
@ -73,6 +79,7 @@ export const ConnectorLinkElasticsearch: React.FC<ConnectorLinkElasticsearchProp
<EuiFlexItem grow={false}>
<span>
<EuiButton
data-test-subj="serverlessSearchConnectorLinkElasticsearchRunFromSourceButton"
iconType={`${assetBasePath}/github_white.svg`}
href="https://github.com/elastic/connectors"
fill
@ -89,10 +96,11 @@ export const ConnectorLinkElasticsearch: React.FC<ConnectorLinkElasticsearchProp
<EuiPanel hasBorder>
<EuiTitle size="xs">
<h3>
{i18n.translate('xpack.serverlessSearch.connectors.variablesTitle', {
defaultMessage: 'Variables for your ',
})}
<EuiCode>elastic/connectors/config.yml</EuiCode>
<FormattedMessage
id="xpack.serverlessSearch.connectors.variablesTitle"
defaultMessage="Variables for your {url}"
values={{ url: <EuiCode>elastic/connectors/config.yml</EuiCode> }}
/>
</h3>
</EuiTitle>
<EuiSpacer />

View file

@ -71,6 +71,7 @@ export const ConnectorOverview: React.FC<ConnectorOverviewProps> = ({ connector
<EuiSpacer />
<span>
<EuiButton
data-test-subj="serverlessSearchConnectorOverviewSyncButton"
color="primary"
disabled={
![ConnectorStatus.CONFIGURED, ConnectorStatus.CONNECTED].includes(connector.status)

View file

@ -116,6 +116,7 @@ export const ConnectorsTable: React.FC = () => {
name: nameLabel,
render: (name: string, connector: Connector) => (
<EuiLink
data-test-subj="serverlessSearchColumnsLink"
onClick={() => navigateToUrl(generatePath(EDIT_CONNECTOR_PATH, { id: connector.id }))}
>
{name || connector.id}
@ -235,6 +236,7 @@ export const ConnectorsTable: React.FC = () => {
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiSelect
data-test-subj="serverlessSearchConnectorsTableSelect"
onChange={(e) => setFilter(e.currentTarget.value as Filter)}
options={filterOptions}
/>
@ -294,6 +296,7 @@ const DeleteConnectorModalAction: React.FC<{ connector: Connector }> = ({ connec
)}
<EuiToolTip content={DELETE_CONNECTOR_LABEL}>
<EuiButtonIcon
data-test-subj="serverlessSearchDeleteConnectorModalActionButton"
aria-label={DELETE_CONNECTOR_LABEL}
onClick={() => setModalIsOpen(true)}
iconType="trash"

View file

@ -97,6 +97,7 @@ export const DeleteConnectorModal: React.FC<DeleteConnectorModalProps> = ({
)}
>
<EuiFieldText
data-test-subj="serverlessSearchDeleteConnectorModalFieldText"
onChange={(e) => setInputConnectorName(e.target.value)}
value={inputConnectorName}
/>

View file

@ -72,7 +72,12 @@ export const EditConnector: React.FC = () => {
</h1>
}
actions={
<EuiButton color="primary" fill onClick={() => navigateToUrl(`./`)}>
<EuiButton
data-test-subj="serverlessSearchEditConnectorGoBackButton"
color="primary"
fill
onClick={() => navigateToUrl(`./`)}
>
{i18n.translate('xpack.serverlessSearch.connectors.goBack', {
defaultMessage: 'Go back',
})}
@ -107,6 +112,7 @@ export const EditConnector: React.FC = () => {
id={'connectorMenu'}
button={
<EuiButtonIcon
data-test-subj="serverlessSearchEditConnectorButton"
aria-label={i18n.translate('xpack.serverlessSearch.connectors.openMenuLabel', {
defaultMessage: 'Open menu',
})}

View file

@ -76,13 +76,18 @@ export const EditDescription: React.FC<EditDescriptionProps> = ({ connector }) =
defaultMessage: 'Description',
})}
labelAppend={
<EuiButtonEmpty size="xs" onClick={() => setIsEditing(true)}>
<EuiButtonEmpty
data-test-subj="serverlessSearchEditDescriptionButton"
size="xs"
onClick={() => setIsEditing(true)}
>
{EDIT_LABEL}
</EuiButtonEmpty>
}
>
{isEditing ? (
<EuiFieldText
data-test-subj="serverlessSearchEditDescriptionFieldText"
onChange={(event) => setNewDescription(event.target.value)}
value={newDescription || ''}
/>
@ -102,6 +107,7 @@ export const EditDescription: React.FC<EditDescriptionProps> = ({ connector }) =
`}
>
<EuiButton
data-test-subj="serverlessSearchEditDescriptionButton"
color="primary"
fill
onClick={() => mutate(newDescription)}
@ -119,6 +125,7 @@ export const EditDescription: React.FC<EditDescriptionProps> = ({ connector }) =
`}
>
<EuiButton
data-test-subj="serverlessSearchEditDescriptionButton"
size="s"
isLoading={isLoading}
onClick={() => {

View file

@ -80,6 +80,7 @@ export const EditName: React.FC<EditNameProps> = ({ connector }) => {
`}
>
<EuiButtonIcon
data-test-subj="serverlessSearchEditNameButton"
color="text"
iconType="pencil"
aria-label={i18n.translate('xpack.serverlessSearch.connectors.editNameLabel', {
@ -97,7 +98,11 @@ export const EditName: React.FC<EditNameProps> = ({ connector }) => {
defaultMessage: 'Name',
})}
</EuiFormLabel>
<EuiFieldText onChange={(event) => setNewName(event.target.value)} value={newName} />
<EuiFieldText
data-test-subj="serverlessSearchEditNameFieldText"
onChange={(event) => setNewName(event.target.value)}
value={newName}
/>
</EuiFlexItem>
<EuiSpacer />
<EuiFlexGroup direction="row" justifyContent="center" alignItems="center">
@ -108,6 +113,7 @@ export const EditName: React.FC<EditNameProps> = ({ connector }) => {
`}
>
<EuiButton
data-test-subj="serverlessSearchEditNameButton"
color="primary"
fill
type="submit"
@ -125,6 +131,7 @@ export const EditName: React.FC<EditNameProps> = ({ connector }) => {
`}
>
<EuiButton
data-test-subj="serverlessSearchEditNameButton"
size="s"
isLoading={isLoading}
onClick={() => {

View file

@ -90,7 +90,10 @@ export const EmptyConnectorsPrompt: React.FC = () => {
defaultMessage="Deploy connector code on your own infrastructure by running from {source}, or using {docker}"
values={{
source: (
<EuiLink href="TODO TODO TODO">
<EuiLink
data-test-subj="serverlessSearchEmptyConnectorsPromptSourceLink"
href="TODO TODO TODO"
>
{i18n.translate(
'xpack.serverlessSearch.connectorsEmpty.sourceLabel',
{ defaultMessage: 'source' }
@ -98,7 +101,10 @@ export const EmptyConnectorsPrompt: React.FC = () => {
</EuiLink>
),
docker: (
<EuiLink href="TODO TODO TODO">
<EuiLink
data-test-subj="serverlessSearchEmptyConnectorsPromptDockerLink"
href="TODO TODO TODO"
>
{i18n.translate(
'xpack.serverlessSearch.connectorsEmpty.dockerLabel',
{ defaultMessage: 'Docker' }
@ -157,7 +163,11 @@ export const EmptyConnectorsPrompt: React.FC = () => {
</EuiPanel>
</EuiFlexItem>
<EuiFlexItem>
<EuiButton fill iconType="plusInCircleFilled">
<EuiButton
data-test-subj="serverlessSearchEmptyConnectorsPromptCreateConnectorButton"
fill
iconType="plusInCircleFilled"
>
{i18n.translate('xpack.serverlessSearch.connectorsEmpty.createConnector', {
defaultMessage: 'Create connector',
})}

View file

@ -56,7 +56,11 @@ export const ConnectorsOverview = () => {
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiText size="s">
<EuiLink target="_blank" href="https://github.com/elastic/connectors">
<EuiLink
data-test-subj="serverlessSearchConnectorsOverviewElasticConnectorsLink"
target="_blank"
href="https://github.com/elastic/connectors"
>
{i18n.translate('xpack.serverlessSearch.connectorsPythonLink', {
defaultMessage: 'elastic/connectors',
})}
@ -67,6 +71,7 @@ export const ConnectorsOverview = () => {
</EuiFlexItem>
<EuiFlexItem>
<EuiButton
data-test-subj="serverlessSearchConnectorsOverviewCreateConnectorButton"
isLoading={isLoading}
fill
iconType="plusInCircleFilled"
@ -87,7 +92,12 @@ export const ConnectorsOverview = () => {
defaultMessage="Sync third-party data sources to Elasticsearch, by deploying Elastic connectors on your own infrastructure. {learnMoreLink}"
values={{
learnMoreLink: (
<EuiLink external target="_blank" href={'TODO TODO'}>
<EuiLink
data-test-subj="serverlessSearchConnectorsOverviewLink"
external
target="_blank"
href={'TODO TODO'}
>
{LEARN_MORE_LABEL}
</EuiLink>
),

View file

@ -51,7 +51,12 @@ const IndexMappingsDocsLink: FunctionComponent<{ docLinks: CoreStart['docLinks']
</p>
</EuiText>
<EuiSpacer size="m" />
<EuiLink href={docLinks.links.enterpriseSearch.ingestPipelines} target="_blank" external>
<EuiLink
data-test-subj="serverlessSearchIndexMappingsDocsLinkLearnMoreAboutIngestPipelinesLink"
href={docLinks.links.enterpriseSearch.ingestPipelines}
target="_blank"
external
>
<FormattedMessage
id="xpack.serverlessSearch.indexMappings.ingestPipelinesDocs.linkLabel"
defaultMessage="Learn more about ingest pipelines"

View file

@ -446,7 +446,11 @@ const OverviewFooter = () => {
<EuiFlexGroup gutterSize="m" alignItems="center">
{cloud.usersAndRolesUrl && (
<FooterButtonContainer>
<EuiButtonEmpty iconType="users" href={cloud.usersAndRolesUrl}>
<EuiButtonEmpty
data-test-subj="serverlessSearchOverviewFooterInviteMoreUsersButton"
iconType="users"
href={cloud.usersAndRolesUrl}
>
{i18n.translate('xpack.serverlessSearch.overview.footer.links.inviteUsers', {
defaultMessage: 'Invite more users',
})}
@ -454,14 +458,22 @@ const OverviewFooter = () => {
</FooterButtonContainer>
)}
<FooterButtonContainer>
<EuiButtonEmpty iconType="heart" href="https://www.elastic.co/community/">
<EuiButtonEmpty
data-test-subj="serverlessSearchOverviewFooterJoinOurCommunityButton"
iconType="heart"
href="https://www.elastic.co/community/"
>
{i18n.translate('xpack.serverlessSearch.overview.footer.links.community', {
defaultMessage: 'Join our community',
})}
</EuiButtonEmpty>
</FooterButtonContainer>
<FooterButtonContainer>
<EuiButtonEmpty iconType="faceHappy" href={docLinks.kibanaFeedback}>
<EuiButtonEmpty
data-test-subj="serverlessSearchOverviewFooterGiveFeedbackButton"
iconType="faceHappy"
href={docLinks.kibanaFeedback}
>
{i18n.translate('xpack.serverlessSearch.overview.footer.links.feedback', {
defaultMessage: 'Give feedback',
})}