From a4953edcad4d26f6f80f063a649d583010c08779 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Efe=20G=C3=BCrkan=20YALAMAN?= Date: Fri, 28 Apr 2023 11:21:45 +0200 Subject: [PATCH] [Enterprise Search] MongoDB Connector cypress test. (#155886) ## Summary Add automated tests via Cypress for MongoDB and Web Crawler happy paths. Tests are quite basic and covers only adding simple one time sync paths. Fill in the `cypress.env.json` with the credentials before running. Mongo specs will run only against a local environment (via `./cypress.sh dev`) as connector has to be running locally as well. ### Checklist Delete any items that are not applicable to this PR. - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --------- Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../enterprise_search/cypress.env.json | 12 +++ .../cypress/e2e/content/basic_crawler.cy.ts | 48 +++++++++- .../content/new_index/mongo_connector.cy.ts | 95 +++++++++++++++++++ .../cypress/e2e/content/selectors.ts | 70 ++++++++++++++ .../enterprise_search/cypress/support/e2e.ts | 9 +- .../components/new_index/new_index_card.tsx | 2 + .../new_index/new_search_index_template.tsx | 2 + .../select_connector/select_connector.tsx | 1 + .../header_actions/syncs_context_menu.tsx | 5 +- .../connector/connector_configuration.tsx | 1 + .../connector_configuration_config.tsx | 1 + .../connector_configuration_form.tsx | 15 ++- .../connector/connector_overview_panels.tsx | 6 +- ...ative_connector_advanced_configuration.tsx | 1 + .../search_index/connector_total_stats.tsx | 4 +- .../add_domain/add_domain_form.tsx | 8 +- .../add_domain_form_submit_button.tsx | 8 +- .../search_index/crawler_total_stats.tsx | 4 +- .../components/search_index/search_index.tsx | 2 + .../search_index/sync_jobs/sync_jobs.tsx | 1 + .../search_indices/search_indices.tsx | 7 +- .../start_crawl_context_menu.tsx | 9 +- 22 files changed, 299 insertions(+), 12 deletions(-) create mode 100644 x-pack/plugins/enterprise_search/cypress.env.json create mode 100644 x-pack/plugins/enterprise_search/cypress/e2e/content/new_index/mongo_connector.cy.ts create mode 100644 x-pack/plugins/enterprise_search/cypress/e2e/content/selectors.ts diff --git a/x-pack/plugins/enterprise_search/cypress.env.json b/x-pack/plugins/enterprise_search/cypress.env.json new file mode 100644 index 0000000000000..14b84557cc90c --- /dev/null +++ b/x-pack/plugins/enterprise_search/cypress.env.json @@ -0,0 +1,12 @@ +{ + "mongo_test": { + "host": "", + "username": "", + "password": "", + "database": "", + "collection": "" + }, + "crawler_test": { + "domain": "" + } +} diff --git a/x-pack/plugins/enterprise_search/cypress/e2e/content/basic_crawler.cy.ts b/x-pack/plugins/enterprise_search/cypress/e2e/content/basic_crawler.cy.ts index 484aa6976072d..e1c3c1583c364 100644 --- a/x-pack/plugins/enterprise_search/cypress/e2e/content/basic_crawler.cy.ts +++ b/x-pack/plugins/enterprise_search/cypress/e2e/content/basic_crawler.cy.ts @@ -7,9 +7,55 @@ import { login } from '../../tasks/login'; +import { NEW_INDEX_CARD, CRAWLER_INDEX, INDEX_OVERVIEW, ROUTES, getIndexRoute } from './selectors'; + describe('Enterprise Search Crawler', () => { it('test', () => { + const envConfig = Cypress.env('crawler_test'); + const indexName = 'cypress-crawler-' + Math.random(); + login(); - cy.visit('/app/enterprise_search/content/search_indices/new_index'); + cy.visit(ROUTES.NEW_INDEX); + + // Crawler selected by default + cy.getBySel(NEW_INDEX_CARD.SELECT_CRAWLER).click(); + + // we are in correct route + cy.url().should('contain', ROUTES.NEW_INDEX); + + cy.getBySel(CRAWLER_INDEX.CREATE_BUTTON).should('be.disabled'); + + // type new name + cy.getBySel(CRAWLER_INDEX.INDEX_NAME_INPUT).type(indexName); + + // create index + cy.getBySel(CRAWLER_INDEX.CREATE_BUTTON).click(); + + // make sure we are in new index + cy.url().should('contain', getIndexRoute(indexName) + 'domain_management'); + + cy.getBySel(CRAWLER_INDEX.DOMAIN_MANAGEMENT.DOMAIN_INPUT).type(envConfig.domain); + cy.getBySel(CRAWLER_INDEX.DOMAIN_MANAGEMENT.DOMAIN_BUTTON).click(); + + cy.getBySel(CRAWLER_INDEX.DOMAIN_MANAGEMENT.SUBMIT_BUTTON).should('be.enabled'); + cy.getBySel(CRAWLER_INDEX.DOMAIN_MANAGEMENT.SUBMIT_BUTTON).click(); + + cy.getBySel(CRAWLER_INDEX.CRAWL_DROPDOWN).should('be.enabled'); + cy.getBySel(CRAWLER_INDEX.CRAWL_DROPDOWN).click(); + cy.getBySel(CRAWLER_INDEX.CRAWL_ALL_DOMAINS).click(); + + // go to overview tab + cy.getBySel(INDEX_OVERVIEW.TABS.OVERVIEW).click(); + + // Page header has index name + cy.get('main header h1').should('contain.text', indexName); + // check Ingestion Type stat is Crawler + cy.getBySel(INDEX_OVERVIEW.STATS.INGESTION_TYPE).should('contain.text', 'Crawler'); + + cy.getBySel(INDEX_OVERVIEW.STATS.DOCUMENT_COUNT).should((el) => { + const text = el.text(); + const count = parseInt(text.match(/[0-9]+/g), 10); + expect(count).to.gt(0); + }); }); }); diff --git a/x-pack/plugins/enterprise_search/cypress/e2e/content/new_index/mongo_connector.cy.ts b/x-pack/plugins/enterprise_search/cypress/e2e/content/new_index/mongo_connector.cy.ts new file mode 100644 index 0000000000000..dd1fd0e4ccb43 --- /dev/null +++ b/x-pack/plugins/enterprise_search/cypress/e2e/content/new_index/mongo_connector.cy.ts @@ -0,0 +1,95 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { login } from '../../../tasks/login'; +import { + CONNECTOR_INDEX, + getIndexRoute, + INDEX_OVERVIEW, + NEW_INDEX_CARD, + NEW_CONNECTOR_PAGE, + ROUTES, + SELECT_CONNECTOR, + SEARCH_INDICES, +} from '../selectors'; + +describe('Enterprise Search MongoDB connector', () => { + it('succesfully syncs documents with single sync', () => { + // Get configuration information from cypress.env.json + const mongoConfig = Cypress.env('mongo_test'); + const indexName = 'cypress-mongodb-' + Math.random(); + const baseUrl = Cypress.config().baseUrl; + login(); + + cy.visit(ROUTES.SEARCH_INDICES_OVERVIEW); + cy.getBySel(SEARCH_INDICES.CREATE_INDEX_BUTTON).click(); + + cy.url().should('eq', baseUrl + ROUTES.NEW_INDEX); + + // select connector + cy.getBySel(NEW_INDEX_CARD.SELECT_CONNECTOR).click(); + + // we are in correct route + cy.url().should('contain', ROUTES.SELECT_CONNECTOR); + + // Select MongoDB from the list + cy.get('#checkableCard-mongodb').should('not.be.selected'); + cy.get('#checkableCard-mongodb-details') + .find('a') + .invoke('attr', 'href') + .should('include', 'connectors-mongodb.html'); + + cy.get('#checkableCard-mongodb').click(); + + cy.getBySel(SELECT_CONNECTOR.SELECT_AND_CONFIGURE_BUTTON).click(); + + // Connector URL, mongo selected + cy.url().should('contain', 'service_type=mongodb'); + + cy.getBySel(NEW_CONNECTOR_PAGE.INDEX_NAME_INPUT).type(indexName); + + // create index + cy.getBySel(NEW_CONNECTOR_PAGE.CREATE_BUTTON).click(); + + // make sure we are in new index route + cy.url().should('contain', getIndexRoute(indexName) + 'configuration'); + + // Fill in connector configuration + cy.getBySel(CONNECTOR_INDEX.getConfigurationRow('host')).type(mongoConfig.host); + cy.getBySel(CONNECTOR_INDEX.getConfigurationRow('user')).type(mongoConfig.username); + cy.getBySel(CONNECTOR_INDEX.getConfigurationRow('password')).type(mongoConfig.password); + cy.getBySel(CONNECTOR_INDEX.getConfigurationRow('database')).type(mongoConfig.database); + cy.getBySel(CONNECTOR_INDEX.getConfigurationRow('collection')).type(mongoConfig.collection); + cy.getBySel(CONNECTOR_INDEX.SAVE_CONFIG).click(); + + // Wait until configuration is saved + cy.getBySel(CONNECTOR_INDEX.EDIT_CONFIG); + cy.getBySel(CONNECTOR_INDEX.SET_SCHEDULE_BUTTON).click(); + + // Scheduling Tab opened + cy.url().should('contain', getIndexRoute(indexName) + 'scheduling'); + + // Start one time sync + cy.getBySel(CONNECTOR_INDEX.HEADER_SYNC_MENU).click(); + cy.getBySel(CONNECTOR_INDEX.HEADER_SYNC_MENU_START).click(); + + // go to overview tab + cy.getBySel(INDEX_OVERVIEW.TABS.OVERVIEW).click(); + + cy.getBySel(INDEX_OVERVIEW.STATS.INGESTION_TYPE).should('contain.text', 'Connector'); + cy.getBySel(INDEX_OVERVIEW.STATS.CONNECTOR_TYPE).should('contain.text', 'MongoDB'); + cy.getBySel(INDEX_OVERVIEW.STATS.INGESTION_STATUS).should('contain.text', 'Configured'); + cy.getBySel(INDEX_OVERVIEW.STATS.INGESTION_STATUS).should('contain.text', 'Connected'); + + // Wait until document count > 0 + cy.getBySel(INDEX_OVERVIEW.STATS.DOCUMENT_COUNT).should((el) => { + const text = el.text(); + const count = parseInt(text.match(/[0-9]+/g), 10); + expect(count).to.gt(0); + }); + }); +}); diff --git a/x-pack/plugins/enterprise_search/cypress/e2e/content/selectors.ts b/x-pack/plugins/enterprise_search/cypress/e2e/content/selectors.ts new file mode 100644 index 0000000000000..e6f1e2e45174d --- /dev/null +++ b/x-pack/plugins/enterprise_search/cypress/e2e/content/selectors.ts @@ -0,0 +1,70 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export const ROUTES = { + CRAWLER_INDEX: '/app/enterprise_search/content/search_indices/new_index/crawler', + NEW_INDEX: '/app/enterprise_search/content/search_indices/new_index', + SEARCH_INDICES_OVERVIEW: '/app/enterprise_search/content/search_indices/', + SELECT_CONNECTOR: '/app/enterprise_search/content/search_indices/new_index/select_connector', +}; + +export const SEARCH_INDICES = { + CREATE_INDEX_BUTTON: 'entSearchContent-searchIndices-createButton', +}; + +export const SELECT_CONNECTOR = { + SELECT_AND_CONFIGURE_BUTTON: 'entSearchContent-connector-selectConnector-selectAndConfigure', +}; + +export const NEW_CONNECTOR_PAGE = { + CREATE_BUTTON: 'entSearchContent-connector-newIndex-createIndex', + INDEX_NAME_INPUT: 'entSearchContent-connector-newIndex-editName', +}; + +export const CONNECTOR_INDEX = { + EDIT_CONFIG: 'entSearchContent-connector-configuration-editConfiguration', + HEADER_SYNC_MENU: 'entSearchContent-connector-header-sync-menu', + HEADER_SYNC_MENU_START: 'entSearchContent-connector-header-sync-startSync', + SAVE_CONFIG: 'entSearchContent-connector-configuration-saveConfiguration', + SET_SCHEDULE_BUTTON: 'entSearchContent-connector-configuration-setScheduleAndSync', + getConfigurationRow: (rowkey: string) => + `entSearchContent-connector-configuration-formrow-${rowkey}`, +}; + +export const NEW_INDEX_CARD = { + SELECT_CONNECTOR: 'entSearchContent-newIndexCard-button-connector', + SELECT_CRAWLER: 'entSearchContent-newIndexCard-button-crawler', +}; + +export const CRAWLER_INDEX = { + CRAWL_ALL_DOMAINS: 'entSearchContent-crawler-startCrawlMenu-crawlAllDomains', + CRAWL_DROPDOWN: 'entSearchContent-crawler-startCrawlMenu-menuButton', + CREATE_BUTTON: 'entSearchContent-crawler-newIndex-createIndex', + DOMAIN_MANAGEMENT: { + DOMAIN_BUTTON: 'entSearchContent-crawler-addDomainForm-validate-button', + DOMAIN_INPUT: 'entSearchContent-crawler-addDomainForm-validate-input', + SUBMIT_BUTTON: 'entSearchContent-crawler-addDomain-submitButton', + }, + INDEX_NAME_INPUT: 'entSearchContent-crawler-newIndex-editName', +}; + +export const INDEX_OVERVIEW = { + STATS: { + CONNECTOR_TYPE: 'entSearchContent-indexOverview-totalStats-connectorType', + DOCUMENT_COUNT: 'entSearchContent-indexOverview-totalStats-documentCount', + INGESTION_STATUS: 'entSearchContent-indexOverview-connectorStats-ingestionStatus', + INGESTION_TYPE: 'entSearchContent-indexOverview-totalStats-ingestionType', + }, + TABS: { + CRAWLER_SCHEDULER: 'entSearchContent-index-crawler-scheduler-tab', + OVERVIEW: 'entSearchContent-index-overview-tab', + }, +}; + +export const getIndexRoute = (indexName: string) => { + return `/app/enterprise_search/content/search_indices/search-${indexName}/`; +}; diff --git a/x-pack/plugins/enterprise_search/cypress/support/e2e.ts b/x-pack/plugins/enterprise_search/cypress/support/e2e.ts index 1e2b130d59973..df0828bfa15cd 100644 --- a/x-pack/plugins/enterprise_search/cypress/support/e2e.ts +++ b/x-pack/plugins/enterprise_search/cypress/support/e2e.ts @@ -29,9 +29,10 @@ declare global { // eslint-disable-next-line @typescript-eslint/no-namespace namespace Cypress { interface Chainable { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + findBySel(value: string, ...args: any[]): Chainable; // eslint-disable-next-line @typescript-eslint/no-explicit-any getBySel(value: string, ...args: any[]): Chainable; - getKibanaVersion(): Chainable; } } } @@ -41,7 +42,13 @@ function getBySel(selector: string, ...args: any[]) { return cy.get(`[data-test-subj="${selector}"]`, ...args); } +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function findBySel(selector: string, ...args: any[]) { + return cy.find(`[data-test-subj="${selector}"]`, ...args); +} + Cypress.Commands.add('getBySel', getBySel); +Cypress.Commands.add('findBySel', findBySel); Cypress.on('uncaught:exception', () => { return false; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/new_index_card.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/new_index_card.tsx index 54e516c3a1f5e..14451c07feadf 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/new_index_card.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/new_index_card.tsx @@ -97,6 +97,7 @@ export const NewIndexCard: React.FC = ({ onSelect, isSelected return ( } title={title} @@ -110,6 +111,7 @@ export const NewIndexCard: React.FC = ({ onSelect, isSelected )} = ({ fullWidth > = ({ { { )} - {getSyncButtonText()} + + {getSyncButtonText()} + } @@ -90,6 +92,7 @@ export const SyncsContextMenu: React.FC = () => { ? [] : [ { { setIsEditing(!isEditing)} > diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/connector_configuration_form.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/connector_configuration_form.tsx index 2c40eb0beafa4..15cc1c098bdb0 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/connector_configuration_form.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/connector_configuration_form.tsx @@ -89,7 +89,12 @@ export const ConnectorConfigurationForm = () => { <> {topSpacing} - + @@ -99,7 +104,12 @@ export const ConnectorConfigurationForm = () => { } return ( - + ); @@ -108,6 +118,7 @@ export const ConnectorConfigurationForm = () => { { { /> - + {ingestionStatus === IngestionStatus.INCOMPLETE ? ( { { return <>; } - const stats: EuiStatProps[] = [ + const stats: EuiStatProps[] & { 'data-test-subj'?: string } = [ { + 'data-test-subj': 'entSearchContent-indexOverview-totalStats-ingestionType', description: i18n.translate( 'xpack.enterpriseSearch.content.searchIndex.totalStats.ingestionTypeCardLabel', { @@ -53,6 +54,7 @@ export const ConnectorTotalStats: React.FC = () => { ), }, { + 'data-test-subj': 'entSearchContent-indexOverview-totalStats-connectorType', description: i18n.translate('xpack.enterpriseSearch.connector.connectorTypePanel.title', { defaultMessage: 'Connector type', }), diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/domain_management/add_domain/add_domain_form.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/domain_management/add_domain/add_domain_form.tsx index 512a69030e382..98d61a2a73662 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/domain_management/add_domain/add_domain_form.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/domain_management/add_domain/add_domain_form.tsx @@ -66,11 +66,17 @@ export const AddDomainForm: React.FC = () => { value={addDomainFormInputValue} onChange={(e) => setAddDomainFormInputValue(e.target.value)} fullWidth + data-test-subj="entSearchContent-crawler-addDomainForm-validate-input" /> - + {i18n.translate( 'xpack.enterpriseSearch.crawler.addDomainForm.validateButtonLabel', { diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/domain_management/add_domain/add_domain_form_submit_button.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/domain_management/add_domain/add_domain_form_submit_button.tsx index 8ba831017df86..8e9d448647673 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/domain_management/add_domain/add_domain_form_submit_button.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/domain_management/add_domain/add_domain_form_submit_button.tsx @@ -21,7 +21,13 @@ export const AddDomainFormSubmitButton: React.FC = () => { const { allowSubmit } = useValues(AddDomainLogic); return ( - + {i18n.translate('xpack.enterpriseSearch.crawler.addDomainForm.submitButtonLabel', { defaultMessage: 'Add domain', })} diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler_total_stats.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler_total_stats.tsx index 7825e93328dc8..8bf7b407d591b 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler_total_stats.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler_total_stats.tsx @@ -29,8 +29,9 @@ export const CrawlerTotalStats: React.FC = () => { const documentCount = indexData?.count ?? 0; const hideStats = isLoading || isError; - const stats: EuiStatProps[] = [ + const stats: EuiStatProps[] & { 'data-test-subj'?: string } = [ { + 'data-test-subj': 'entSearchContent-indexOverview-totalStats-ingestionType', description: i18n.translate( 'xpack.enterpriseSearch.content.searchIndex.totalStats.ingestionTypeCardLabel', { @@ -56,6 +57,7 @@ export const CrawlerTotalStats: React.FC = () => { title: domains.length, }, { + 'data-test-subj': 'entSearchContent-indexOverview-totalStats-documentCount', description: i18n.translate( 'xpack.enterpriseSearch.content.searchIndex.totalStats.documentCountCardLabel', { diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/search_index.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/search_index.tsx index 6b4e1c475f9fb..cad08d5252b02 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/search_index.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/search_index.tsx @@ -98,6 +98,7 @@ export const SearchIndex: React.FC = () => { const ALL_INDICES_TABS: EuiTabbedContentTab[] = [ { content: , + 'data-test-subj': 'entSearchContent-index-overview-tab', id: SearchIndexTabId.OVERVIEW, name: i18n.translate('xpack.enterpriseSearch.content.searchIndex.overviewTabLabel', { defaultMessage: 'Overview', @@ -167,6 +168,7 @@ export const SearchIndex: React.FC = () => { }, { content: , + 'data-test-subj': 'entSearchContent-index-crawler-scheduler-tab', id: SearchIndexTabId.SCHEDULING, name: i18n.translate('xpack.enterpriseSearch.content.searchIndex.schedulingTabLabel', { defaultMessage: 'Scheduling', diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/sync_jobs/sync_jobs.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/sync_jobs/sync_jobs.tsx index c885160693f44..b82b555950380 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/sync_jobs/sync_jobs.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/sync_jobs/sync_jobs.tsx @@ -115,6 +115,7 @@ export const SyncJobs: React.FC = () => { <> setSyncJobFlyout(undefined)} syncJob={syncJobFlyout} /> { ? [] : [ - + {i18n.translate( 'xpack.enterpriseSearch.content.searchIndices.create.buttonTitle', { diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/shared/crawler_status_indicator/start_crawl_context_menu.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/shared/crawler_status_indicator/start_crawl_context_menu.tsx index b85839351e2ea..09b69ab40ac61 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/shared/crawler_status_indicator/start_crawl_context_menu.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/shared/crawler_status_indicator/start_crawl_context_menu.tsx @@ -25,7 +25,13 @@ export const StartCrawlContextMenu: React.FC = () => { return ( + {i18n.translate( 'xpack.enterpriseSearch.crawler.crawlerStatusIndicator.retryCrawlButtonLabel', { @@ -48,6 +54,7 @@ export const StartCrawlContextMenu: React.FC = () => { startCrawl(); }} icon="play" + data-test-subj="entSearchContent-crawler-startCrawlMenu-crawlAllDomains" > {i18n.translate( 'xpack.enterpriseSearch.crawler.startCrawlContextMenu.crawlAllDomainsMenuLabel',