[Uptime] UI Monitor Management/Synthetics Service e2e tests - add environment variables for service (#122552)

* add environment variables for service

* add SYNTHETICS_SERVICE_MANIFEST and basic tests

* Update x-pack/plugins/uptime/e2e/playwright_run.ts

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Dominique Clarke 2022-01-18 15:53:10 -05:00 committed by GitHub
parent fc64d172e7
commit 5789546067
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 413 additions and 2 deletions

View file

@ -92,6 +92,15 @@ export KIBANA_DOCKER_USERNAME
KIBANA_DOCKER_PASSWORD="$(retry 5 5 vault read -field=password secret/kibana-issues/dev/container-registry)"
export KIBANA_DOCKER_PASSWORD
SYNTHETICS_SERVICE_USERNAME="$(retry 5 5 vault read -field=username secret/kibana-issues/dev/kibana-ci-synthetics-credentials)"
export SYNTHETICS_SERVICE_USERNAME
SYNTHETICS_SERVICE_PASSWORD="$(retry 5 5 vault read -field=password secret/kibana-issues/dev/kibana-ci-synthetics-credentials)"
export SYNTHETICS_SERVICE_PASSWORD
SYNTHETICS_SERVICE_MANIFEST="$(retry 5 5 vault read -field=manifest secret/kibana-issues/dev/kibana-ci-synthetics-credentials)"
export SYNTHETICS_SERVICE_MANIFEST
# Setup Failed Test Reporter Elasticsearch credentials
{
TEST_FAILURES_ES_CLOUD_ID=$(retry 5 5 vault read -field=cloud_id secret/kibana-issues/dev/failed_tests_reporter_es)

View file

@ -44,6 +44,11 @@ async function config({ readConfigFile }: FtrConfigProviderContext) {
`--elasticsearch.username=kibana_system`,
`--elasticsearch.password=changeme`,
'--xpack.reporting.enabled=false',
`--xpack.uptime.unsafe.service.manifestUrl=${process.env.SYNTHETICS_SERVICE_MANIFEST}`,
`--xpack.uptime.unsafe.service.username=${process.env.SYNTHETICS_SERVICE_USERNAME}`,
`--xpack.uptime.unsafe.service.password=${process.env.SYNTHETICS_SERVICE_PASSWORD}`,
'--xpack.uptime.unsafe.service.enabled=true',
'--xpack.uptime.ui.unsafe.monitorManagement.enabled=true',
],
},
};

View file

@ -7,5 +7,6 @@
export * from './data_view_permissions';
export * from './uptime.journey';
export * from './monitor_management.journey';
export * from './step_duration.journey';
export * from './alerts';

View file

@ -0,0 +1,136 @@
/*
* 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 { journey, step, expect, before, Page } from '@elastic/synthetics';
import { monitorManagementPageProvider } from '../page_objects/monitor_management';
journey('Monitor Management', async ({ page, params }: { page: Page; params: any }) => {
const uptime = monitorManagementPageProvider({ page, kibanaUrl: params.kibanaUrl });
const basicMonitorDetails = {
name: 'Sample monitor',
location: 'US Central',
schedule: '@every 3m',
apmServiceName: 'service',
};
const deleteMonitor = async () => {
const isSuccessful = await uptime.deleteMonitor();
expect(isSuccessful).toBeTruthy();
};
before(async () => {
await uptime.waitForLoadingToFinish();
});
step('Go to monitor-management', async () => {
await uptime.navigateToMonitorManagement();
});
step('login to Kibana', async () => {
await uptime.loginToKibana();
});
step('create monitor http monitor', async () => {
const monitorDetails = {
...basicMonitorDetails,
url: 'https://elastic.co',
locations: [basicMonitorDetails.location],
};
await uptime.clickAddMonitor();
await uptime.createBasicHTTPMonitorDetails(monitorDetails);
const isSuccessful = await uptime.confirmAndSave();
expect(isSuccessful).toBeTruthy();
});
step('view HTTP details in monitor management UI', async () => {
const monitorDetails = {
...basicMonitorDetails,
url: 'https://elastic.co',
};
await uptime.clickAddMonitor();
await uptime.findMonitorConfiguration(monitorDetails);
});
step('delete http monitor', async () => {
await deleteMonitor();
});
step('create monitor tcp monitor', async () => {
const monitorDetails = {
...basicMonitorDetails,
host: 'smtp.gmail.com:587',
locations: [basicMonitorDetails.location],
};
await uptime.clickAddMonitor();
await uptime.createBasicTCPMonitorDetails(monitorDetails);
const isSuccessful = await uptime.confirmAndSave();
expect(isSuccessful).toBeTruthy();
});
step('view TCP details in monitor management UI', async () => {
const monitorDetails = {
...basicMonitorDetails,
host: 'smtp.gmail.com:587',
};
await uptime.clickAddMonitor();
await uptime.findMonitorConfiguration(monitorDetails);
});
step('delete tcp monitor', async () => {
await deleteMonitor();
});
step('create basic ICMP monitor', async () => {
const monitorDetails = {
...basicMonitorDetails,
host: '1.1.1.1',
locations: [basicMonitorDetails.location],
};
await uptime.clickAddMonitor();
await uptime.createBasicICMPMonitorDetails(monitorDetails);
const isSuccessful = await uptime.confirmAndSave();
expect(isSuccessful).toBeTruthy();
});
step('view ICMP details in monitor management UI', async () => {
const monitorDetails = {
...basicMonitorDetails,
host: '1.1.1.1',
};
await uptime.clickAddMonitor();
await uptime.findMonitorConfiguration(monitorDetails);
});
step('delete ICMP monitor', async () => {
await deleteMonitor();
});
step('create basic Browser monitor', async () => {
const monitorDetails = {
...basicMonitorDetails,
inlineScript: 'step("test step", () => {})',
locations: [basicMonitorDetails.location],
};
await uptime.clickAddMonitor();
await uptime.createBasicBrowserMonitorDetails(monitorDetails, true);
const isSuccessful = await uptime.confirmAndSave();
expect(isSuccessful).toBeTruthy();
});
step('view ICMP details in monitor management UI', async () => {
const monitorDetails = {
...basicMonitorDetails,
host: '1.1.1.1',
};
await uptime.clickAddMonitor();
await uptime.findMonitorConfiguration(monitorDetails);
});
step('delete ICMP monitor', async () => {
await deleteMonitor();
});
});

View file

@ -0,0 +1,28 @@
/*
* 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 { Page } from '@elastic/synthetics';
export function loginPageProvider({ page }: { page: Page; kibanaUrl: string }) {
return {
async waitForLoadingToFinish() {
while (true) {
if ((await page.$('[data-test-subj=kbnLoadingMessage]')) === null) break;
await page.waitForTimeout(5 * 1000);
}
},
async loginToKibana() {
await page.fill('[data-test-subj=loginUsername]', 'elastic', {
timeout: 60 * 1000,
});
await page.fill('[data-test-subj=loginPassword]', 'changeme');
await page.click('[data-test-subj=loginSubmit]');
await this.waitForLoadingToFinish();
},
};
}

View file

@ -0,0 +1,183 @@
/*
* 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 { Page } from '@elastic/synthetics';
import { loginPageProvider } from './login';
import { utilsPageProvider } from './utils';
export function monitorManagementPageProvider({
page,
kibanaUrl,
}: {
page: Page;
kibanaUrl: string;
}) {
const monitorManagement = `${kibanaUrl}/app/uptime/manage-monitors`;
const addMonitor = `${kibanaUrl}/app/uptime/add-monitor`;
return {
...loginPageProvider({ page, kibanaUrl }),
...utilsPageProvider({ page }),
async navigateToMonitorManagement() {
await page.goto(monitorManagement, {
waitUntil: 'networkidle',
});
},
async navigateToAddMonitor() {
await page.goto(addMonitor, {
waitUntil: 'networkidle',
});
},
async clickAddMonitor() {
await page.click('text=Add monitor');
},
async deleteMonitor() {
await this.clickByTestSubj('monitorManagementDeleteMonitor');
return await this.findByTestSubj('uptimeDeleteMonitorSuccess');
},
async findMonitorConfiguration(monitorConfig: Record<string, string>) {
const values = Object.values(monitorConfig);
for (let i = 0; i < values.length; i++) {
await this.findByText(values[i]);
}
},
async selectMonitorType(monitorType: string) {
await this.selectByTestSubj('syntheticsMonitorTypeField', monitorType);
},
async ensureIsOnMonitorConfigPage() {
await page.isVisible('[data-test-subj=monitorSettingsSection]');
},
async confirmAndSave(isEditPage?: boolean) {
await this.ensureIsOnMonitorConfigPage();
if (isEditPage) {
await page.click('text=Update monitor');
} else {
await page.click('text=Save monitor');
}
return await this.findByTestSubj('uptimeAddMonitorSuccess');
},
async fillCodeEditor(value: string) {
await page.fill('[data-test-subj=codeEditorContainer] textarea', value);
},
async selectLocations({ locations }: { locations: string[] }) {
await this.clickByTestSubj('syntheticsServiceLocationsComboBox');
for (let i = 0; i < locations.length; i++) {
await page.click(`text=${locations[i]}`);
}
},
async createBasicMonitorDetails({
name,
apmServiceName,
locations,
}: {
name: string;
apmServiceName: string;
locations: string[];
}) {
await this.fillByTestSubj('monitorManagementMonitorName', name);
await this.fillByTestSubj('syntheticsAPMServiceName', apmServiceName);
await this.selectLocations({ locations });
},
async createBasicHTTPMonitorDetails({
name,
url,
apmServiceName,
locations,
}: {
name: string;
url: string;
apmServiceName: string;
locations: string[];
}) {
await this.createBasicMonitorDetails({ name, apmServiceName, locations });
await this.fillByTestSubj('syntheticsUrlField', url);
},
async createBasicTCPMonitorDetails({
name,
host,
apmServiceName,
locations,
}: {
name: string;
host: string;
apmServiceName: string;
locations: string[];
}) {
await this.selectMonitorType('tcp');
await this.createBasicMonitorDetails({ name, apmServiceName, locations });
await this.fillByTestSubj('syntheticsTCPHostField', host);
},
async createBasicICMPMonitorDetails({
name,
host,
apmServiceName,
locations,
}: {
name: string;
host: string;
apmServiceName: string;
locations: string[];
}) {
await this.selectMonitorType('icmp');
await this.createBasicMonitorDetails({ name, apmServiceName, locations });
await this.fillByTestSubj('syntheticsICMPHostField', host);
},
async createBasicBrowserMonitorDetails(
{
name,
inlineScript,
zipUrl,
folder,
params,
username,
password,
apmServiceName,
locations,
}: {
name: string;
inlineScript?: string;
zipUrl?: string;
folder?: string;
params?: string;
username?: string;
password?: string;
apmServiceName: string;
locations: string[];
},
isInline: boolean = false
) {
await this.selectMonitorType('browser');
await this.createBasicMonitorDetails({ name, apmServiceName, locations });
if (isInline && inlineScript) {
await this.clickByTestSubj('syntheticsSourceTab__inline');
await this.fillCodeEditor(inlineScript);
return;
}
await this.fillByTestSubj('syntheticsBrowserZipUrl', zipUrl || '');
await this.fillByTestSubj('syntheticsBrowserZipUrlFolder', folder || '');
await this.fillByTestSubj('syntheticsBrowserZipUrlUsername', username || '');
await this.fillByTestSubj('syntheticsBrowserZipUrlPassword', password || '');
await this.fillCodeEditor(params || '');
},
};
}

View file

@ -0,0 +1,47 @@
/*
* 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 { expect, Page } from '@elastic/synthetics';
export function utilsPageProvider({ page }: { page: Page }) {
return {
byTestId(testId: string) {
return `[data-test-subj=${testId}]`;
},
async waitForLoadingToFinish() {
while (true) {
if ((await page.$(this.byTestId('kbnLoadingMessage'))) === null) break;
await page.waitForTimeout(5 * 1000);
}
},
async assertText({ text }: { text: string }) {
await page.waitForSelector(`text=${text}`);
expect(await page.$(`text=${text}`)).toBeTruthy();
},
async fillByTestSubj(dataTestSubj: string, value: string) {
await page.fill(`[data-test-subj=${dataTestSubj}]`, value);
},
async selectByTestSubj(dataTestSubj: string, value: string) {
await page.selectOption(`[data-test-subj=${dataTestSubj}]`, value);
},
async clickByTestSubj(dataTestSubj: string) {
await page.click(`[data-test-subj=${dataTestSubj}]`);
},
async findByTestSubj(dataTestSubj: string) {
return await page.locator(`[data-test-subj=${dataTestSubj}]`);
},
async findByText(text: string) {
return await page.locator(`text=${text}`);
},
};
}

View file

@ -50,6 +50,7 @@ export const MonitorNameAndLocation = ({ validate }: Props) => {
fullWidth={true}
name="name"
onChange={(event) => setName(event.target.value)}
data-test-subj="monitorManagementMonitorName"
/>
</EuiFormRow>
<ServiceLocations

View file

@ -41,13 +41,13 @@ export const Actions = ({ id, setRefresh }: Props) => {
}
if (status === FETCH_STATUS.FAILURE) {
notifications.toasts.danger({
title: <p data-test-subj="uptimeAddMonitorFailure">{MONITOR_DELETE_FAILURE_LABEL}</p>,
title: <p data-test-subj="uptimeDeleteMonitorFailure">{MONITOR_DELETE_FAILURE_LABEL}</p>,
toastLifeTimeMs: 3000,
});
} else if (status === FETCH_STATUS.SUCCESS) {
setRefresh(true);
notifications.toasts.success({
title: <p data-test-subj="uptimeAddMonitorSuccess">{MONITOR_DELETE_SUCCESS_LABEL}</p>,
title: <p data-test-subj="uptimeDeleteMonitorSuccess">{MONITOR_DELETE_SUCCESS_LABEL}</p>,
toastLifeTimeMs: 3000,
});
}
@ -71,6 +71,7 @@ export const Actions = ({ id, setRefresh }: Props) => {
iconType="trash"
onClick={handleDelete}
aria-label={DELETE_MONITOR_LABEL}
data-test-subj="monitorManagementDeleteMonitor"
/>
)}
</EuiFlexItem>