diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/service_overview.spec.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/service_overview.spec.ts index 8239ff4765f74..3bbc69b31a98f 100644 --- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/service_overview.spec.ts +++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/service_overview.spec.ts @@ -19,25 +19,11 @@ const baseUrl = url.format({ }); const apiRequestsToIntercept = [ - { - endpoint: - '/internal/apm/services/opbeans-node/transactions/charts/latency?*', - aliasName: 'latencyRequest', - }, - { - endpoint: '/internal/apm/services/opbeans-node/throughput?*', - aliasName: 'throughputRequest', - }, { endpoint: '/internal/apm/services/opbeans-node/transactions/groups/main_statistics?*', aliasName: 'transactionsGroupsMainStadisticsRequest', }, - { - endpoint: - '/internal/apm/services/opbeans-node/transactions/charts/error_rate?*', - aliasName: 'errorRateRequest', - }, { endpoint: '/internal/apm/services/opbeans-node/errors/groups/main_statistics?*', @@ -52,16 +38,34 @@ const apiRequestsToIntercept = [ endpoint: '/internal/apm/services/opbeans-node/dependencies?*', aliasName: 'dependenciesRequest', }, +]; + +const apiRequestsToInterceptWithComparison = [ { endpoint: - '/internal/apm/services/opbeans-node/service_overview_instances/main_statistics?*', - aliasName: 'instancesMainStadisticsRequest', + '/internal/apm/services/opbeans-node/transactions/charts/latency?*', + aliasName: 'latencyRequest', + }, + { + endpoint: '/internal/apm/services/opbeans-node/throughput?*', + aliasName: 'throughputRequest', + }, + { + endpoint: + '/internal/apm/services/opbeans-node/transactions/charts/error_rate?*', + aliasName: 'errorRateRequest', }, { endpoint: '/internal/apm/services/opbeans-node/transactions/groups/detailed_statistics?*', aliasName: 'transactionsGroupsDetailedStadisticsRequest', }, + { + endpoint: + '/internal/apm/services/opbeans-node/service_overview_instances/main_statistics?*', + aliasName: 'instancesMainStadisticsRequest', + }, + { endpoint: '/internal/apm/services/opbeans-node/service_overview_instances/detailed_statistics?*', @@ -69,16 +73,17 @@ const apiRequestsToIntercept = [ }, ]; -const aliasNames = apiRequestsToIntercept.map( +const aliasNamesNoComparison = apiRequestsToIntercept.map( ({ aliasName }) => `@${aliasName}` ); -describe('Service Overview', () => { - beforeEach(() => { - cy.loginAsReadOnlyUser(); - cy.visit(baseUrl); - }); +const aliasNamesWithComparison = apiRequestsToInterceptWithComparison.map( + ({ aliasName }) => `@${aliasName}` +); +const aliasNames = [...aliasNamesNoComparison, ...aliasNamesWithComparison]; + +describe('Service Overview', () => { before(async () => { await synthtrace.index( opbeans({ @@ -92,97 +97,121 @@ describe('Service Overview', () => { await synthtrace.clean(); }); - it('persists transaction type selected when clicking on Transactions tab', () => { - cy.get('[data-test-subj="headerFilterTransactionType"]').should( - 'have.value', - 'request' - ); - cy.get('[data-test-subj="headerFilterTransactionType"]').select('Worker'); - cy.get('[data-test-subj="headerFilterTransactionType"]').should( - 'have.value', - 'Worker' - ); - cy.contains('Transactions').click(); - cy.get('[data-test-subj="headerFilterTransactionType"]').should( - 'have.value', - 'Worker' - ); - }); + describe('renders', () => { + before(() => { + cy.loginAsReadOnlyUser(); + cy.visit(baseUrl); + }); + it('transaction latency chart', () => { + cy.get('[data-test-subj="latencyChart"]'); + }); - it('persists transaction type selected when clicking on View Transactions link', () => { - cy.get('[data-test-subj="headerFilterTransactionType"]').should( - 'have.value', - 'request' - ); - cy.get('[data-test-subj="headerFilterTransactionType"]').select('Worker'); - cy.get('[data-test-subj="headerFilterTransactionType"]').should( - 'have.value', - 'Worker' - ); + it('throughput chart', () => { + cy.get('[data-test-subj="throughput"]'); + }); - cy.contains('View transactions').click(); - cy.get('[data-test-subj="headerFilterTransactionType"]').should( - 'have.value', - 'Worker' - ); - }); + it('transactions group table', () => { + cy.get('[data-test-subj="transactionsGroupTable"]'); + }); - it('renders transaction latency chart', () => { - cy.get('[data-test-subj="latencyChart"]'); - }); + it('error table', () => { + cy.get('[data-test-subj="serviceOverviewErrorsTable"]'); + }); - it('renders throughput chart', () => { - cy.get('[data-test-subj="throughput"]'); - }); + it('dependencies table', () => { + cy.get('[data-test-subj="dependenciesTable"]'); + }); - it('renders transactions group table', () => { - cy.get('[data-test-subj="transactionsGroupTable"]'); - }); + it('instances latency distribution chart', () => { + cy.get('[data-test-subj="instancesLatencyDistribution"]'); + }); - it('renders error table', () => { - cy.get('[data-test-subj="serviceOverviewErrorsTable"]'); + it('instances table', () => { + cy.get('[data-test-subj="serviceOverviewInstancesTable"]'); + }); }); - it('renders dependencies table', () => { - cy.get('[data-test-subj="dependenciesTable"]'); - }); + describe('transactions', () => { + beforeEach(() => { + cy.loginAsReadOnlyUser(); + cy.visit(baseUrl); + }); - it('renders instances latency distribution chart', () => { - cy.get('[data-test-subj="instancesLatencyDistribution"]'); - }); + it('persists transaction type selected when clicking on Transactions tab', () => { + cy.get('[data-test-subj="headerFilterTransactionType"]').should( + 'have.value', + 'request' + ); + cy.get('[data-test-subj="headerFilterTransactionType"]').select('Worker'); + cy.get('[data-test-subj="headerFilterTransactionType"]').should( + 'have.value', + 'Worker' + ); + cy.contains('Transactions').click(); + cy.get('[data-test-subj="headerFilterTransactionType"]').should( + 'have.value', + 'Worker' + ); + }); + + it('persists transaction type selected when clicking on View Transactions link', () => { + cy.get('[data-test-subj="headerFilterTransactionType"]').should( + 'have.value', + 'request' + ); + cy.get('[data-test-subj="headerFilterTransactionType"]').select('Worker'); + cy.get('[data-test-subj="headerFilterTransactionType"]').should( + 'have.value', + 'Worker' + ); - it('renders instances table', () => { - cy.get('[data-test-subj="serviceOverviewInstancesTable"]'); + cy.contains('View transactions').click(); + cy.get('[data-test-subj="headerFilterTransactionType"]').should( + 'have.value', + 'Worker' + ); + }); }); - it('hides dependency tab when RUM service', () => { - cy.intercept('GET', '/internal/apm/services/opbeans-rum/agent?*').as( - 'agentRequest' - ); - cy.visit( - url.format({ - pathname: '/app/apm/services/opbeans-rum/overview', - query: { rangeFrom: start, rangeTo: end }, - }) - ); - cy.contains('Overview'); - cy.contains('Transactions'); - cy.contains('Error'); - cy.contains('Service Map'); - // Waits until the agent request is finished to check the tab. - cy.wait('@agentRequest'); - cy.get('.euiTabs .euiTab__content').then((elements) => { - elements.map((index, element) => { - expect(element.innerText).to.not.equal('Dependencies'); + describe('when RUM service', () => { + before(() => { + cy.loginAsReadOnlyUser(); + cy.visit( + url.format({ + pathname: '/app/apm/services/opbeans-rum/overview', + query: { rangeFrom: start, rangeTo: end }, + }) + ); + }); + + it('hides dependency tab when RUM service', () => { + cy.intercept('GET', '/internal/apm/services/opbeans-rum/agent?*').as( + 'agentRequest' + ); + cy.contains('Overview'); + cy.contains('Transactions'); + cy.contains('Error'); + cy.contains('Service Map'); + // Waits until the agent request is finished to check the tab. + cy.wait('@agentRequest'); + cy.get('.euiTabs .euiTab__content').then((elements) => { + elements.map((index, element) => { + expect(element.innerText).to.not.equal('Dependencies'); + }); }); }); }); describe('Calls APIs', () => { beforeEach(() => { + cy.loginAsReadOnlyUser(); + cy.visit(baseUrl); apiRequestsToIntercept.map(({ endpoint, aliasName }) => { cy.intercept('GET', endpoint).as(aliasName); }); + apiRequestsToInterceptWithComparison.map(({ endpoint, aliasName }) => { + cy.intercept('GET', endpoint).as(aliasName); + }); }); it('with the correct environment when changing the environment', () => { @@ -197,9 +226,8 @@ describe('Service Overview', () => { }); it('when clicking the refresh button', () => { - cy.wait(aliasNames, { requestTimeout: 10000 }); cy.contains('Refresh').click(); - cy.wait(aliasNames); + cy.wait(aliasNames, { requestTimeout: 10000 }); }); it('when selecting a different time range and clicking the update button', () => { @@ -225,7 +253,10 @@ describe('Service Overview', () => { 'have.value', 'week' ); - cy.wait(aliasNames, { requestTimeout: 10000 }); + cy.expectAPIsToHaveBeenCalledWith({ + apisIntercepted: aliasNamesWithComparison, + value: 'comparisonStart', + }); }); }); }); diff --git a/x-pack/plugins/apm/public/components/app/service_overview/service_overview_errors_table/index.tsx b/x-pack/plugins/apm/public/components/app/service_overview/service_overview_errors_table/index.tsx index 28d1067168095..0b7d3c32957e2 100644 --- a/x-pack/plugins/apm/public/components/app/service_overview/service_overview_errors_table/index.tsx +++ b/x-pack/plugins/apm/public/components/app/service_overview/service_overview_errors_table/index.tsx @@ -180,95 +180,91 @@ export function ServiceOverviewErrorsTable({ serviceName }: Props) { }); return ( -
- - - - - -

- {i18n.translate( - 'xpack.apm.serviceOverview.errorsTableTitle', - { - defaultMessage: 'Errors', - } - )} -

-
-
- - - {i18n.translate( - 'xpack.apm.serviceOverview.errorsTableLinkText', - { - defaultMessage: 'View errors', - } - )} - - -
-
- - + + + + +

+ {i18n.translate('xpack.apm.serviceOverview.errorsTableTitle', { + defaultMessage: 'Errors', + })} +

+
+
+ + + {i18n.translate('xpack.apm.serviceOverview.errorsTableLinkText', { + defaultMessage: 'View errors', + })} + + +
+
+ + + - { - setTableOptions({ - pageIndex: newTableOptions.page?.index ?? 0, - sort: newTableOptions.sort - ? { - field: newTableOptions.sort.field as SortField, - direction: newTableOptions.sort.direction, - } - : DEFAULT_SORT, - }); - }} - sorting={{ - enableAllColumns: true, - sort, - }} - /> - - -
-
+ noItemsMessage={ + status === FETCH_STATUS.LOADING + ? i18n.translate( + 'xpack.apm.serviceOverview.errorsTable.loading', + { defaultMessage: 'Loading...' } + ) + : i18n.translate( + 'xpack.apm.serviceOverview.errorsTable.noResults', + { defaultMessage: 'No errors found' } + ) + } + columns={columns} + items={items} + pagination={{ + pageIndex, + pageSize: PAGE_SIZE, + totalItemCount: totalItems, + pageSizeOptions: [PAGE_SIZE], + hidePerPageOptions: true, + }} + loading={status === FETCH_STATUS.LOADING} + onChange={(newTableOptions: { + page?: { + index: number; + }; + sort?: { field: string; direction: SortDirection }; + }) => { + setTableOptions({ + pageIndex: newTableOptions.page?.index ?? 0, + sort: newTableOptions.sort + ? { + field: newTableOptions.sort.field as SortField, + direction: newTableOptions.sort.direction, + } + : DEFAULT_SORT, + }); + }} + sorting={{ + enableAllColumns: true, + sort, + }} + /> + + + ); } diff --git a/x-pack/plugins/apm/public/components/app/service_overview/service_overview_instances_table/index.tsx b/x-pack/plugins/apm/public/components/app/service_overview/service_overview_instances_table/index.tsx index b1dcd4f059edd..c41ad329ea863 100644 --- a/x-pack/plugins/apm/public/components/app/service_overview/service_overview_instances_table/index.tsx +++ b/x-pack/plugins/apm/public/components/app/service_overview/service_overview_instances_table/index.tsx @@ -145,53 +145,55 @@ export function ServiceOverviewInstancesTable({ }; return ( -
- - - -

- {i18n.translate('xpack.apm.serviceOverview.instancesTableTitle', { - defaultMessage: 'Instances', - })} -

-
-
- - - - - -
-
+ + + +

+ {i18n.translate('xpack.apm.serviceOverview.instancesTableTitle', { + defaultMessage: 'Instances', + })} +

+
+
+ + + + + +
); } diff --git a/x-pack/plugins/apm/public/components/shared/dependencies_table/index.tsx b/x-pack/plugins/apm/public/components/shared/dependencies_table/index.tsx index 7e31fe35acd29..2d68cb5e9dae7 100644 --- a/x-pack/plugins/apm/public/components/shared/dependencies_table/index.tsx +++ b/x-pack/plugins/apm/public/components/shared/dependencies_table/index.tsx @@ -205,39 +205,41 @@ export function DependenciesTable(props: Props) { ); return ( -
- - - - - -

{title}

-
-
- {link && {link}} -
-
- - - - - -
-
+ + + + + +

{title}

+
+
+ {link && {link}} +
+
+ + + + + +
); } diff --git a/x-pack/plugins/apm/public/components/shared/transactions_table/index.tsx b/x-pack/plugins/apm/public/components/shared/transactions_table/index.tsx index 420763bbc9e96..4c1063173d929 100644 --- a/x-pack/plugins/apm/public/components/shared/transactions_table/index.tsx +++ b/x-pack/plugins/apm/public/components/shared/transactions_table/index.tsx @@ -229,103 +229,105 @@ export function TransactionsTable({ const isNotInitiated = status === FETCH_STATUS.NOT_INITIATED; return ( -
- - - + + + + + +

+ {i18n.translate('xpack.apm.transactionsTable.title', { + defaultMessage: 'Transactions', + })} +

+
+
+ {!hideViewTransactionsLink && ( - -

- {i18n.translate('xpack.apm.transactionsTable.title', { - defaultMessage: 'Transactions', - })} -

-
+ + {i18n.translate('xpack.apm.transactionsTable.linkText', { + defaultMessage: 'View transactions', + })} +
- {!hideViewTransactionsLink && ( - - - {i18n.translate('xpack.apm.transactionsTable.linkText', { - defaultMessage: 'View transactions', - })} - - + )} +
+
+ {showAggregationAccurateCallout && !isAggregationAccurate && ( + + - - {showAggregationAccurateCallout && !isAggregationAccurate && ( - - -

- xpack.apm.ui.transactionGroupBucketSize - ), - }} - /> + color="danger" + iconType="alert" + > +

+ xpack.apm.ui.transactionGroupBucketSize + ), + }} + /> - - {i18n.translate( - 'xpack.apm.transactionsTable.cardinalityWarning.docsLink', - { defaultMessage: 'Learn more in the docs' } - )} - -

-
-
- )} + + {i18n.translate( + 'xpack.apm.transactionsTable.cardinalityWarning.docsLink', + { defaultMessage: 'Learn more in the docs' } + )} + +

+ +
+ )} + - - + - - - + hidePerPageOptions={hidePerPageOptions} + /> + -
-
+ + ); }