[Uptime] Add UI Monitor Management and Synthetics Service e2e tests (#123410)

* add synthetics pipeline script

* remove artifacts step

* Revert "remove artifacts step"

This reverts commit ba751bca84.

* update pre_command and environment variables

* update grep

* update precommand and login

* update timeout

* adjust journey reusability

* adjust monitor breadcrumb journey

* adjust grep

* add logs

* update login username and password

* Update x-pack/plugins/uptime/e2e/page_objects/login.tsx

* Update .buildkite/scripts/steps/functional/synthetics.sh

* Update x-pack/plugins/uptime/scripts/e2e.js

* adjust grep

* update tests

* adjust script

* adjust journey names

* adjust grep

* increase timeout

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Dominique Clarke 2022-01-26 13:54:51 -05:00 committed by GitHub
parent 4d3a792f9e
commit f197095f0b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 235 additions and 119 deletions

View file

@ -101,6 +101,15 @@ 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
SYNTHETICS_REMOTE_KIBANA_USERNAME="$(retry 5 5 vault read -field=username secret/kibana-issues/dev/kibana-ci-synthetics-remote-credentials)"
export SYNTHETICS_REMOTE_KIBANA_USERNAME
SYNTHETICS_REMOTE_KIBANA_PASSWORD="$(retry 5 5 vault read -field=password secret/kibana-issues/dev/kibana-ci-synthetics-remote-credentials)"
export SYNTHETICS_REMOTE_KIBANA_PASSWORD
SYNTHETICS_REMOTE_KIBANA_URL="$(retry 5 5 vault read -field=url secret/kibana-issues/dev/kibana-ci-synthetics-remote-credentials)"
export SYNTHETICS_REMOTE_KIBANA_URL
# 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

@ -0,0 +1,17 @@
#!/usr/bin/env bash
set -euo pipefail
source .buildkite/scripts/common/util.sh
.buildkite/scripts/bootstrap.sh
.buildkite/scripts/download_build_artifacts.sh
export JOB=kibana-uptime-playwright
echo "--- Uptime @elastic/synthetics Tests"
cd "$XPACK_DIR"
checks-reporter-with-killswitch "Uptime @elastic/synthetics Tests" \
node plugins/uptime/scripts/e2e.js --kibana-install-dir "$KIBANA_BUILD_LOCATION" --grep "MonitorManagement*"

View file

@ -5,139 +5,154 @@
* 2.0.
*/
import { journey, step, expect, before, Page } from '@elastic/synthetics';
import { journey, step, expect, before, after, Page } from '@elastic/synthetics';
import { monitorManagementPageProvider } from '../page_objects/monitor_management';
import { DataStream } from '../../common/runtime_types/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 basicMonitorDetails = {
location: 'US Central',
schedule: '@every 3m',
};
const httpName = 'http monitor';
const icmpName = 'icmp monitor';
const tcpName = 'tcp monitor';
const browserName = 'browser monitor';
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 = {
const configuration = {
[DataStream.HTTP]: {
monitorConfig: {
...basicMonitorDetails,
name: httpName,
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 = {
apmServiceName: 'Sample APM Service',
},
monitorDetails: {
...basicMonitorDetails,
name: httpName,
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 = {
},
},
[DataStream.TCP]: {
monitorConfig: {
...basicMonitorDetails,
name: tcpName,
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 = {
apmServiceName: 'Sample APM Service',
},
monitorDetails: {
...basicMonitorDetails,
name: tcpName,
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 = {
},
},
[DataStream.ICMP]: {
monitorConfig: {
...basicMonitorDetails,
name: icmpName,
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 = {
apmServiceName: 'Sample APM Service',
},
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 = {
name: icmpName,
hosts: '1.1.1.1',
},
},
[DataStream.BROWSER]: {
monitorConfig: {
...basicMonitorDetails,
name: browserName,
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 = {
apmServiceName: 'Sample APM Service',
},
monitorDetails: {
...basicMonitorDetails,
host: '1.1.1.1',
};
await uptime.clickAddMonitor();
await uptime.findMonitorConfiguration(monitorDetails);
});
name: browserName,
},
},
};
step('delete ICMP monitor', async () => {
await deleteMonitor();
const createMonitorJourney = ({
monitorName,
monitorType,
monitorConfig,
monitorDetails,
}: {
monitorName: string;
monitorType: DataStream;
monitorConfig: Record<string, string | string[]>;
monitorDetails: Record<string, string>;
}) => {
journey(
`MonitorManagement-${monitorType}`,
async ({ page, params }: { page: Page; params: any }) => {
const uptime = monitorManagementPageProvider({ page, kibanaUrl: params.kibanaUrl });
const isRemote = process.env.SYNTHETICS_REMOTE_ENABLED;
const deleteMonitor = async () => {
await uptime.navigateToMonitorManagement();
const isSuccessful = await uptime.deleteMonitor();
expect(isSuccessful).toBeTruthy();
};
before(async () => {
await uptime.waitForLoadingToFinish();
});
after(async () => {
await deleteMonitor();
});
step('Go to monitor-management', async () => {
await uptime.navigateToMonitorManagement();
});
step('login to Kibana', async () => {
await uptime.loginToKibana();
const invalid = await page.locator(
`text=Username or password is incorrect. Please try again.`
);
expect(await invalid.isVisible()).toBeFalsy();
});
step(`create ${monitorType} monitor`, async () => {
await uptime.clickAddMonitor();
await uptime.createMonitor({ monitorConfig, monitorType });
const isSuccessful = await uptime.confirmAndSave();
expect(isSuccessful).toBeTruthy();
});
step(`view ${monitorType} details in monitor management UI`, async () => {
await uptime.navigateToMonitorManagement();
const hasFailure = await uptime.findMonitorConfiguration(monitorDetails);
expect(hasFailure).toBeFalsy();
});
if (isRemote) {
step('view results in overview page', async () => {
await uptime.navigateToOverviewPage();
await page.waitForSelector(`text=${monitorName}`, { timeout: 160 * 1000 });
});
}
}
);
};
Object.keys(configuration).forEach((type) => {
createMonitorJourney({
monitorType: type as DataStream,
monitorName: `${type} monitor`,
monitorConfig: configuration[type as DataStream].monitorConfig,
monitorDetails: configuration[type as DataStream].monitorDetails,
});
});
journey('Monitor Management breadcrumbs', async ({ page, params }: { page: Page; params: any }) => {
const uptime = monitorManagementPageProvider({ page, kibanaUrl: params.kibanaUrl });
const basicMonitorDetails = {
const defaultMonitorDetails = {
name: 'Sample monitor',
location: 'US Central',
schedule: '@every 3m',
@ -171,7 +186,7 @@ journey('Monitor Management breadcrumbs', async ({ page, params }: { page: Page;
step('create monitor http monitor', async () => {
const monitorDetails = {
...basicMonitorDetails,
...defaultMonitorDetails,
url: 'https://elastic.co',
locations: [basicMonitorDetails.location],
};

View file

@ -6,7 +6,17 @@
*/
import { Page } from '@elastic/synthetics';
export function loginPageProvider({ page }: { page: Page; kibanaUrl: string }) {
export function loginPageProvider({
page,
isRemote,
username = 'elastic',
password = 'changeme',
}: {
page: Page;
isRemote: boolean;
username?: string;
password?: string;
}) {
return {
async waitForLoadingToFinish() {
while (true) {
@ -15,10 +25,13 @@ export function loginPageProvider({ page }: { page: Page; kibanaUrl: string }) {
}
},
async loginToKibana() {
await page.fill('[data-test-subj=loginUsername]', 'elastic', {
if (isRemote) {
await page.click('text="Log in with Elasticsearch"');
}
await page.fill('[data-test-subj=loginUsername]', username, {
timeout: 60 * 1000,
});
await page.fill('[data-test-subj=loginPassword]', 'changeme');
await page.fill('[data-test-subj=loginPassword]', password);
await page.click('[data-test-subj=loginSubmit]');

View file

@ -6,6 +6,7 @@
*/
import { Page } from '@elastic/synthetics';
import { DataStream } from '../../common/runtime_types/monitor_management';
import { loginPageProvider } from './login';
import { utilsPageProvider } from './utils';
@ -16,11 +17,21 @@ export function monitorManagementPageProvider({
page: Page;
kibanaUrl: string;
}) {
const monitorManagement = `${kibanaUrl}/app/uptime/manage-monitors`;
const addMonitor = `${kibanaUrl}/app/uptime/add-monitor`;
const remoteKibanaUrl = process.env.SYNTHETICS_REMOTE_KIBANA_URL;
const remoteUsername = process.env.SYNTHETICS_REMOTE_KIBANA_USERNAME;
const remotePassword = process.env.SYNTHETICS_REMOTE_KIBANA_PASSWORD;
const isRemote = Boolean(process.env.SYNTHETICS_REMOTE_ENABLED);
const basePath = isRemote ? remoteKibanaUrl : kibanaUrl;
const monitorManagement = `${basePath}/app/uptime/manage-monitors`;
const addMonitor = `${basePath}/app/uptime/add-monitor`;
const overview = `${basePath}/app/uptime`;
return {
...loginPageProvider({ page, kibanaUrl }),
...loginPageProvider({
page,
isRemote,
username: isRemote ? remoteUsername : 'elastic',
password: isRemote ? remotePassword : 'changeme',
}),
...utilsPageProvider({ page }),
async navigateToMonitorManagement() {
@ -35,6 +46,12 @@ export function monitorManagementPageProvider({
});
},
async navigateToOverviewPage() {
await page.goto(overview, {
waitUntil: 'networkidle',
});
},
async clickAddMonitor() {
await page.click('text=Add monitor');
},
@ -183,5 +200,34 @@ export function monitorManagementPageProvider({
await this.fillByTestSubj('syntheticsBrowserZipUrlPassword', password || '');
await this.fillCodeEditor(params || '');
},
async createMonitor({
monitorConfig,
monitorType,
}: {
monitorConfig: Record<string, string | string[]>;
monitorType: DataStream;
}) {
switch (monitorType) {
case DataStream.HTTP:
// @ts-ignore
await this.createBasicHTTPMonitorDetails(monitorConfig);
break;
case DataStream.TCP:
// @ts-ignore
await this.createBasicTCPMonitorDetails(monitorConfig);
break;
case DataStream.ICMP:
// @ts-ignore
await this.createBasicICMPMonitorDetails(monitorConfig);
break;
case DataStream.BROWSER:
// @ts-ignore
await this.createBasicBrowserMonitorDetails(monitorConfig, true);
break;
default:
break;
}
},
};
}

View file

@ -37,11 +37,11 @@ export function utilsPageProvider({ page }: { page: Page }) {
},
async findByTestSubj(dataTestSubj: string) {
return await page.locator(`[data-test-subj=${dataTestSubj}]`);
return await page.waitForSelector(`[data-test-subj=${dataTestSubj}]`);
},
async findByText(text: string) {
return await page.locator(`text=${text}`);
return await page.waitForSelector(`text=${text}`);
},
};
}

View file

@ -19,6 +19,11 @@ const listOfJourneys = [
'StepsDuration',
'TlsFlyoutInAlertingApp',
'StatusFlyoutInAlertingApp',
'MonitorManagement-http',
'MonitorManagement-tcp',
'MonitorManagement-icmp',
'MonitorManagement-browser',
'MonitorManagement breadcrumbs',
] as const;
export function playwrightRunTests({ headless, match }: { headless: boolean; match?: string }) {

View file

@ -10,5 +10,8 @@
{
"path": "../../apm/tsconfig.json",
},
{
"path": "../tsconfig.json",
}
]
}

View file

@ -59,9 +59,17 @@ if (server) {
const config = './playwright_run.ts';
function executeRunner() {
if (runner) {
if (server) {
childProcess.execSync(
`node ../../../scripts/${ftrScript} --config ${config} --kibana-install-dir '${kibanaInstallDir}' --headless ${headless} --grep ${grep}`,
`node ../../../scripts/${ftrScript} --config ${config} --kibana-install-dir '${kibanaInstallDir}'`,
{
cwd: e2eDir,
stdio: 'inherit',
}
);
} else if (runner) {
childProcess.execSync(
`node ../../../scripts/${ftrScript} --config ${config} --kibana-install-dir '${kibanaInstallDir}' --headless ${headless} --grep '${grep}'`,
{
cwd: e2eDir,
stdio: 'inherit',
@ -69,7 +77,7 @@ function executeRunner() {
);
} else {
childProcess.execSync(
`node ../../../scripts/${ftrScript} --config ${config} --kibana-install-dir '${kibanaInstallDir}' `,
`node ../../../scripts/${ftrScript} --config ${config} --kibana-install-dir '${kibanaInstallDir}' --grep '${grep}'`,
{
cwd: e2eDir,
stdio: 'inherit',