* creating e2e test comparison feature * fixing test * comparison e2e tests * addressing comments Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Cauê Marcondes <55978943+cauemarcondes@users.noreply.github.com>
This commit is contained in:
parent
8f2cb58b70
commit
e28e63cdfa
|
@ -362,11 +362,11 @@
|
|||
"resize-observer-polyfill": "^1.5.0",
|
||||
"rison-node": "1.0.2",
|
||||
"rxjs": "^6.5.5",
|
||||
"safe-squel": "^5.12.5",
|
||||
"seedrandom": "^3.0.5",
|
||||
"semver": "^7.3.2",
|
||||
"set-value": "^3.0.2",
|
||||
"source-map-support": "^0.5.19",
|
||||
"safe-squel": "^5.12.5",
|
||||
"stats-lite": "^2.2.0",
|
||||
"strip-ansi": "^6.0.0",
|
||||
"style-it": "^2.1.3",
|
||||
|
@ -668,6 +668,7 @@
|
|||
"cypress-multi-reporters": "^1.4.0",
|
||||
"cypress-pipe": "^2.0.0",
|
||||
"cypress-promise": "^1.1.0",
|
||||
"cypress-real-events": "^1.4.0",
|
||||
"debug": "^2.6.9",
|
||||
"del-cli": "^3.0.1",
|
||||
"delete-empty": "^2.0.0",
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
describe('Home page', () => {
|
||||
before(() => {
|
||||
cy.loginAsSuperUser();
|
||||
});
|
||||
it('Redirects to service page with rangeFrom and rangeTo added to the URL', () => {
|
||||
cy.visit('/app/apm');
|
||||
|
||||
cy.url().should(
|
||||
'include',
|
||||
'app/apm/services?rangeFrom=now-15m&rangeTo=now'
|
||||
);
|
||||
cy.get('.euiTabs .euiTab-isSelected').contains('Services');
|
||||
});
|
||||
});
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* 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 url from 'url';
|
||||
import archives_metadata from '../../fixtures/es_archiver/archives_metadata';
|
||||
import { esArchiverLoad, esArchiverUnload } from '../../tasks/es_archiver';
|
||||
const { start, end } = archives_metadata['apm_8.0.0'];
|
||||
|
||||
describe('Home page', () => {
|
||||
before(() => {
|
||||
esArchiverLoad('apm_8.0.0');
|
||||
cy.loginAsReadOnlyUser();
|
||||
});
|
||||
after(() => {
|
||||
esArchiverUnload('apm_8.0.0');
|
||||
});
|
||||
it('Redirects to service page with rangeFrom and rangeTo added to the URL', () => {
|
||||
const baseUrl = url.format({
|
||||
pathname: '/app/apm',
|
||||
query: { rangeFrom: start, rangeTo: end },
|
||||
});
|
||||
|
||||
cy.visit(baseUrl);
|
||||
cy.get('.euiTabs .euiTab-isSelected').contains('Services');
|
||||
});
|
||||
});
|
|
@ -0,0 +1,203 @@
|
|||
/*
|
||||
* 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 url from 'url';
|
||||
import moment from 'moment';
|
||||
import archives_metadata from '../../../fixtures/es_archiver/archives_metadata';
|
||||
import { esArchiverLoad, esArchiverUnload } from '../../../tasks/es_archiver';
|
||||
|
||||
const { start, end } = archives_metadata['apm_8.0.0'];
|
||||
|
||||
const serviceOverviewPath = '/app/apm/services/opbeans-java/overview';
|
||||
const baseUrl = url.format({
|
||||
pathname: serviceOverviewPath,
|
||||
query: { rangeFrom: start, rangeTo: end },
|
||||
});
|
||||
|
||||
const apisToIntercept = [
|
||||
{
|
||||
endpoint: '/api/apm/services/opbeans-java/transactions/charts/latency',
|
||||
as: 'latencyChartRequest',
|
||||
},
|
||||
{
|
||||
endpoint: '/api/apm/services/opbeans-java/throughput',
|
||||
as: 'throughputChartRequest',
|
||||
},
|
||||
{
|
||||
endpoint: '/api/apm/services/opbeans-java/transactions/charts/error_rate',
|
||||
as: 'errorRateChartRequest',
|
||||
},
|
||||
{
|
||||
endpoint:
|
||||
'/api/apm/services/opbeans-java/transactions/groups/detailed_statistics',
|
||||
as: 'transactionGroupsDetailedRequest',
|
||||
},
|
||||
{
|
||||
endpoint: '/api/apm/services/opbeans-java/error_groups/detailed_statistics',
|
||||
as: 'errorGroupsDetailedRequest',
|
||||
},
|
||||
{
|
||||
endpoint:
|
||||
'/api/apm/services/opbeans-java/service_overview_instances/detailed_statistics',
|
||||
as: 'instancesDetailedRequest',
|
||||
},
|
||||
];
|
||||
|
||||
describe('Service overview: Time Comparison', () => {
|
||||
before(() => {
|
||||
esArchiverLoad('apm_8.0.0');
|
||||
});
|
||||
after(() => {
|
||||
esArchiverUnload('apm_8.0.0');
|
||||
});
|
||||
beforeEach(() => {
|
||||
cy.loginAsReadOnlyUser();
|
||||
});
|
||||
|
||||
it('enables by default the time comparison feature with Last 24 hours selected', () => {
|
||||
cy.visit(serviceOverviewPath);
|
||||
cy.url().should('include', 'comparisonEnabled=true&comparisonType=day');
|
||||
});
|
||||
|
||||
describe('when comparison is toggled off', () => {
|
||||
it('disables select box', () => {
|
||||
cy.visit(baseUrl);
|
||||
cy.contains('opbeans-java');
|
||||
|
||||
// Comparison is enabled by default
|
||||
cy.get('[data-test-subj="comparisonSelect"]').should('be.enabled');
|
||||
|
||||
// toggles off comparison
|
||||
cy.contains('Comparison').click();
|
||||
cy.get('[data-test-subj="comparisonSelect"]').should('be.disabled');
|
||||
});
|
||||
|
||||
it('calls APIs without comparison time range', () => {
|
||||
apisToIntercept.map(({ endpoint, as }) => {
|
||||
cy.intercept('GET', endpoint).as(as);
|
||||
});
|
||||
cy.visit(baseUrl);
|
||||
cy.contains('opbeans-java');
|
||||
|
||||
cy.get('[data-test-subj="comparisonSelect"]').should('be.enabled');
|
||||
const comparisonStartEnd =
|
||||
'comparisonStart=2020-12-08T13%3A26%3A03.865Z&comparisonEnd=2020-12-08T13%3A57%3A00.000Z';
|
||||
// When the page loads it fetches all APIs with comparison time range
|
||||
cy.wait(apisToIntercept.map(({ as }) => `@${as}`)).then(
|
||||
(interceptions) => {
|
||||
interceptions.map((interception) => {
|
||||
expect(interception.request.url).include(comparisonStartEnd);
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
// toggles off comparison
|
||||
cy.contains('Comparison').click();
|
||||
cy.get('[data-test-subj="comparisonSelect"]').should('be.disabled');
|
||||
// When comparison is disabled APIs are called withou comparison time range
|
||||
cy.wait(apisToIntercept.map(({ as }) => `@${as}`)).then(
|
||||
(interceptions) => {
|
||||
interceptions.map((interception) => {
|
||||
expect(interception.request.url).not.include(comparisonStartEnd);
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('changes comparison type', () => {
|
||||
apisToIntercept.map(({ endpoint, as }) => {
|
||||
cy.intercept('GET', endpoint).as(as);
|
||||
});
|
||||
cy.visit(serviceOverviewPath);
|
||||
cy.contains('opbeans-java');
|
||||
// opens the page with "Day before" selected
|
||||
cy.get('[data-test-subj="comparisonSelect"]').should('have.value', 'day');
|
||||
|
||||
// selects another comparison type
|
||||
cy.get('[data-test-subj="comparisonSelect"]').select('week');
|
||||
cy.get('[data-test-subj="comparisonSelect"]').should('have.value', 'week');
|
||||
});
|
||||
|
||||
it('changes comparison type when a new time range is selected', () => {
|
||||
cy.visit(serviceOverviewPath);
|
||||
cy.contains('opbeans-java');
|
||||
// Time comparison default value
|
||||
cy.get('[data-test-subj="comparisonSelect"]').should('have.value', 'day');
|
||||
cy.contains('Day before');
|
||||
cy.contains('Week before');
|
||||
|
||||
cy.changeTimeRange('Today');
|
||||
cy.get('[data-test-subj="comparisonSelect"]').should(
|
||||
'have.value',
|
||||
'period'
|
||||
);
|
||||
cy.get('[data-test-subj="comparisonSelect"]').should(
|
||||
'not.contain.text',
|
||||
'Day before'
|
||||
);
|
||||
cy.get('[data-test-subj="comparisonSelect"]').should(
|
||||
'not.contain.text',
|
||||
'Week before'
|
||||
);
|
||||
|
||||
cy.changeTimeRange('Last 24 hours');
|
||||
cy.get('[data-test-subj="comparisonSelect"]').should('have.value', 'day');
|
||||
cy.contains('Day before');
|
||||
cy.contains('Week before');
|
||||
|
||||
cy.changeTimeRange('Last 7 days');
|
||||
cy.get('[data-test-subj="comparisonSelect"]').should('have.value', 'week');
|
||||
cy.get('[data-test-subj="comparisonSelect"]').should(
|
||||
'contain.text',
|
||||
'Week before'
|
||||
);
|
||||
cy.get('[data-test-subj="comparisonSelect"]').should(
|
||||
'not.contain.text',
|
||||
'Day before'
|
||||
);
|
||||
cy.contains('Week before');
|
||||
|
||||
cy.changeTimeRange('Last 30 days');
|
||||
cy.get('[data-test-subj="comparisonSelect"]').should(
|
||||
'have.value',
|
||||
'period'
|
||||
);
|
||||
cy.get('[data-test-subj="comparisonSelect"]').should(
|
||||
'not.contain.text',
|
||||
'Day before'
|
||||
);
|
||||
cy.get('[data-test-subj="comparisonSelect"]').should(
|
||||
'not.contain.text',
|
||||
'Week before'
|
||||
);
|
||||
});
|
||||
|
||||
it('hovers over throughput chart shows previous and current period', () => {
|
||||
apisToIntercept.map(({ endpoint, as }) => {
|
||||
cy.intercept('GET', endpoint).as(as);
|
||||
});
|
||||
cy.visit(
|
||||
url.format({
|
||||
pathname: serviceOverviewPath,
|
||||
query: {
|
||||
rangeFrom: moment(end).subtract(15, 'minutes').toISOString(),
|
||||
rangeTo: end,
|
||||
},
|
||||
})
|
||||
);
|
||||
cy.contains('opbeans-java');
|
||||
cy.wait('@throughputChartRequest');
|
||||
cy.get('[data-test-subj="throughput"]')
|
||||
.get('#echHighlighterClipPath__throughput')
|
||||
.realHover({ position: 'center' });
|
||||
cy.contains('Previous period');
|
||||
cy.contains('0 tpm');
|
||||
|
||||
cy.contains('Throughput');
|
||||
cy.contains('0 tpm');
|
||||
});
|
||||
});
|
|
@ -4,6 +4,7 @@
|
|||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
import 'cypress-real-events/support';
|
||||
|
||||
Cypress.Commands.add('loginAsReadOnlyUser', () => {
|
||||
cy.loginAs({ username: 'apm_read_user', password: 'changeme' });
|
||||
|
@ -33,3 +34,8 @@ Cypress.Commands.add(
|
|||
});
|
||||
}
|
||||
);
|
||||
|
||||
Cypress.Commands.add('changeTimeRange', (value: string) => {
|
||||
cy.get('[data-test-subj="superDatePickerToggleQuickMenuButton"]').click();
|
||||
cy.contains(value).click();
|
||||
});
|
||||
|
|
|
@ -10,5 +10,6 @@ declare namespace Cypress {
|
|||
loginAsReadOnlyUser(): void;
|
||||
loginAsSuperUser(): void;
|
||||
loginAs(params: { username: string; password: string }): void;
|
||||
changeTimeRange(value: string): void;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,25 +7,19 @@
|
|||
|
||||
export const esArchiverLoad = (folder: string) => {
|
||||
cy.exec(
|
||||
`node ../../../../scripts/es_archiver load ${folder} --dir ./cypress/fixtures/es_archiver --config ../../../test/functional/config.js --es-url ${Cypress.env(
|
||||
'ELASTICSEARCH_URL'
|
||||
)} --kibana-url ${Cypress.config().baseUrl}`
|
||||
`node ../../../../scripts/es_archiver load ${folder} --dir ./cypress/fixtures/es_archiver --config ../../../test/functional/config.js`
|
||||
);
|
||||
};
|
||||
|
||||
export const esArchiverUnload = (folder: string) => {
|
||||
cy.exec(
|
||||
`node ../../../../scripts/es_archiver unload ${folder} --dir ./cypress/fixtures/es_archiver --config ../../../test/functional/config.js --es-url ${Cypress.env(
|
||||
'ELASTICSEARCH_URL'
|
||||
)} --kibana-url ${Cypress.config().baseUrl}`
|
||||
`node ../../../../scripts/es_archiver unload ${folder} --dir ./cypress/fixtures/es_archiver --config ../../../test/functional/config.js`
|
||||
);
|
||||
};
|
||||
|
||||
export const esArchiverResetKibana = () => {
|
||||
cy.exec(
|
||||
`node ../../../../scripts/es_archiver empty-kibana-index --config ../../../test/functional/config.js --es-url ${Cypress.env(
|
||||
'ELASTICSEARCH_URL'
|
||||
)} --kibana-url ${Cypress.config().baseUrl}`,
|
||||
`node ../../../../scripts/es_archiver empty-kibana-index --config ../../../test/functional/config.js`,
|
||||
{ failOnNonZeroExit: false }
|
||||
);
|
||||
};
|
||||
|
|
|
@ -9,7 +9,8 @@
|
|||
"compilerOptions": {
|
||||
"types": [
|
||||
"cypress",
|
||||
"node"
|
||||
"node",
|
||||
"cypress-real-events"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -15,9 +15,16 @@ interface Props {
|
|||
status: FETCH_STATUS;
|
||||
height: number;
|
||||
children: React.ReactNode;
|
||||
id?: string;
|
||||
}
|
||||
|
||||
export function ChartContainer({ children, height, status, hasData }: Props) {
|
||||
export function ChartContainer({
|
||||
children,
|
||||
height,
|
||||
status,
|
||||
hasData,
|
||||
id,
|
||||
}: Props) {
|
||||
if (!hasData && status === FETCH_STATUS.LOADING) {
|
||||
return <LoadingChartPlaceholder height={height} />;
|
||||
}
|
||||
|
@ -26,7 +33,11 @@ export function ChartContainer({ children, height, status, hasData }: Props) {
|
|||
return <FailedChartPlaceholder height={height} />;
|
||||
}
|
||||
|
||||
return <div style={{ height }}>{children}</div>;
|
||||
return (
|
||||
<div style={{ height }} data-test-subj={id}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function LoadingChartPlaceholder({ height }: { height: number }) {
|
||||
|
|
|
@ -98,7 +98,12 @@ export function TimeseriesChart({
|
|||
const xDomain = isEmpty ? { min: 0, max: 1 } : { min, max };
|
||||
|
||||
return (
|
||||
<ChartContainer hasData={!isEmpty} height={height} status={fetchStatus}>
|
||||
<ChartContainer
|
||||
hasData={!isEmpty}
|
||||
height={height}
|
||||
status={fetchStatus}
|
||||
id={id}
|
||||
>
|
||||
<Chart ref={chartRef} id={id}>
|
||||
<Settings
|
||||
onBrushEnd={({ x }) => onBrushEnd({ x, history })}
|
||||
|
|
|
@ -10665,6 +10665,11 @@ cypress-promise@^1.1.0:
|
|||
resolved "https://registry.yarnpkg.com/cypress-promise/-/cypress-promise-1.1.0.tgz#f2d66965945fe198431aaf692d5157cea9d47b25"
|
||||
integrity sha512-DhIf5PJ/a0iY+Yii6n7Rbwq+9TJxU4pupXYzf9mZd8nPG0AzQrj9i+pqINv4xbI2EV1p+PKW3maCkR7oPG4GrA==
|
||||
|
||||
cypress-real-events@^1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/cypress-real-events/-/cypress-real-events-1.4.0.tgz#39575031a4020581e0bbf105d7a306ee57d94f48"
|
||||
integrity sha512-1s4BQN1D++vFSuaad0qKsWcoApM5tQqPBFyDJEa6JeCZIsAdgMdGLuKi5QNIdl5KTJix0jxglzFJAThyz3borQ==
|
||||
|
||||
cypress@^6.8.0:
|
||||
version "6.8.0"
|
||||
resolved "https://registry.yarnpkg.com/cypress/-/cypress-6.8.0.tgz#8338f39212a8f71e91ff8c017a1b6e22d823d8c1"
|
||||
|
|
Loading…
Reference in a new issue