[Uptime] [Synthetics Integration] browser functional tests (#110648)
* uptime - synthetics integration - add browser functional tests * focus tests * unfocus test * Uptime - Synthetics Integration - adds stringToJsonFormatter
This commit is contained in:
parent
9dec97b5f4
commit
e25c9dfece
6 changed files with 277 additions and 3 deletions
|
@ -6,7 +6,12 @@
|
|||
*/
|
||||
|
||||
import { BrowserFields, ConfigKeys } from '../types';
|
||||
import { Formatter, commonFormatters, arrayToJsonFormatter } from '../common/formatters';
|
||||
import {
|
||||
Formatter,
|
||||
commonFormatters,
|
||||
arrayToJsonFormatter,
|
||||
stringToJsonFormatter,
|
||||
} from '../common/formatters';
|
||||
|
||||
export type BrowserFormatMap = Record<keyof BrowserFields, Formatter>;
|
||||
|
||||
|
@ -15,7 +20,7 @@ export const browserFormatters: BrowserFormatMap = {
|
|||
[ConfigKeys.SOURCE_ZIP_USERNAME]: null,
|
||||
[ConfigKeys.SOURCE_ZIP_PASSWORD]: null,
|
||||
[ConfigKeys.SOURCE_ZIP_FOLDER]: null,
|
||||
[ConfigKeys.SOURCE_INLINE]: (fields) => JSON.stringify(fields[ConfigKeys.SOURCE_INLINE]),
|
||||
[ConfigKeys.SOURCE_INLINE]: (fields) => stringToJsonFormatter(fields[ConfigKeys.SOURCE_INLINE]),
|
||||
[ConfigKeys.PARAMS]: null,
|
||||
[ConfigKeys.SCREENSHOTS]: null,
|
||||
[ConfigKeys.SYNTHETICS_ARGS]: (fields) =>
|
||||
|
|
|
@ -68,6 +68,7 @@ export const SourceField = ({ onChange, defaultConfig = defaultValues }: Props)
|
|||
{
|
||||
id: 'syntheticsBrowserZipURLConfig',
|
||||
name: zipUrlLabel,
|
||||
'data-test-subj': `syntheticsSourceTab__zipUrl`,
|
||||
content: (
|
||||
<>
|
||||
<EuiSpacer size="m" />
|
||||
|
@ -92,6 +93,7 @@ export const SourceField = ({ onChange, defaultConfig = defaultValues }: Props)
|
|||
setConfig((prevConfig) => ({ ...prevConfig, zipUrl: value }))
|
||||
}
|
||||
value={config.zipUrl}
|
||||
data-test-subj="syntheticsBrowserZipUrl"
|
||||
/>
|
||||
</EuiFormRow>
|
||||
<EuiFormRow
|
||||
|
@ -114,6 +116,7 @@ export const SourceField = ({ onChange, defaultConfig = defaultValues }: Props)
|
|||
setConfig((prevConfig) => ({ ...prevConfig, folder: value }))
|
||||
}
|
||||
value={config.folder}
|
||||
data-test-subj="syntheticsBrowserZipUrlFolder"
|
||||
/>
|
||||
</EuiFormRow>
|
||||
<EuiFormRow
|
||||
|
@ -142,6 +145,7 @@ export const SourceField = ({ onChange, defaultConfig = defaultValues }: Props)
|
|||
languageId={MonacoEditorLangId.JSON}
|
||||
onChange={(code) => setConfig((prevConfig) => ({ ...prevConfig, params: code }))}
|
||||
value={config.params}
|
||||
data-test-subj="syntheticsBrowserZipUrlParams"
|
||||
/>
|
||||
</EuiFormRow>
|
||||
<EuiFormRow
|
||||
|
@ -164,6 +168,7 @@ export const SourceField = ({ onChange, defaultConfig = defaultValues }: Props)
|
|||
setConfig((prevConfig) => ({ ...prevConfig, username: value }))
|
||||
}
|
||||
value={config.username}
|
||||
data-test-subj="syntheticsBrowserZipUrlUsername"
|
||||
/>
|
||||
</EuiFormRow>
|
||||
<EuiFormRow
|
||||
|
@ -186,6 +191,7 @@ export const SourceField = ({ onChange, defaultConfig = defaultValues }: Props)
|
|||
setConfig((prevConfig) => ({ ...prevConfig, password: value }))
|
||||
}
|
||||
value={config.password}
|
||||
data-test-subj="syntheticsBrowserZipUrlPassword"
|
||||
/>
|
||||
</EuiFormRow>
|
||||
</>
|
||||
|
@ -199,6 +205,7 @@ export const SourceField = ({ onChange, defaultConfig = defaultValues }: Props)
|
|||
defaultMessage="Inline script"
|
||||
/>
|
||||
),
|
||||
'data-test-subj': `syntheticsSourceTab__inline`,
|
||||
content: (
|
||||
<EuiFormRow
|
||||
isInvalid={!config.inlineScript}
|
||||
|
|
|
@ -5,7 +5,12 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { arrayToJsonFormatter, objectToJsonFormatter, secondsToCronFormatter } from './formatters';
|
||||
import {
|
||||
arrayToJsonFormatter,
|
||||
objectToJsonFormatter,
|
||||
stringToJsonFormatter,
|
||||
secondsToCronFormatter,
|
||||
} from './formatters';
|
||||
|
||||
describe('formatters', () => {
|
||||
describe('cronToSecondsNormalizer', () => {
|
||||
|
@ -33,4 +38,16 @@ describe('formatters', () => {
|
|||
expect(objectToJsonFormatter({})).toEqual(null);
|
||||
});
|
||||
});
|
||||
|
||||
describe('stringToJsonFormatter', () => {
|
||||
it('takes a string and returns an json string', () => {
|
||||
expect(stringToJsonFormatter('step("test step", () => {})')).toEqual(
|
||||
'"step(\\"test step\\", () => {})"'
|
||||
);
|
||||
});
|
||||
|
||||
it('returns null if the string is falsy', () => {
|
||||
expect(stringToJsonFormatter('')).toEqual(null);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -30,3 +30,5 @@ export const secondsToCronFormatter = (value: string = '') => (value ? `${value}
|
|||
|
||||
export const objectToJsonFormatter = (value: Record<string, string> = {}) =>
|
||||
Object.keys(value).length ? JSON.stringify(value) : null;
|
||||
|
||||
export const stringToJsonFormatter = (value: string = '') => (value ? JSON.stringify(value) : null);
|
||||
|
|
|
@ -72,6 +72,58 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
|
|||
],
|
||||
...config,
|
||||
},
|
||||
...(monitorType === 'browser'
|
||||
? [
|
||||
{
|
||||
data_stream: {
|
||||
dataset: 'browser.network',
|
||||
type: 'synthetics',
|
||||
},
|
||||
id: `${getSyntheticsPolicy(agentFullPolicy)?.streams?.[1]?.id}`,
|
||||
processors: [
|
||||
{
|
||||
add_observer_metadata: {
|
||||
geo: {
|
||||
name: 'Fleet managed',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
add_fields: {
|
||||
fields: {
|
||||
'monitor.fleet_managed': true,
|
||||
},
|
||||
target: '',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
data_stream: {
|
||||
dataset: 'browser.screenshot',
|
||||
type: 'synthetics',
|
||||
},
|
||||
id: `${getSyntheticsPolicy(agentFullPolicy)?.streams?.[2]?.id}`,
|
||||
processors: [
|
||||
{
|
||||
add_observer_metadata: {
|
||||
geo: {
|
||||
name: 'Fleet managed',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
add_fields: {
|
||||
fields: {
|
||||
'monitor.fleet_managed': true,
|
||||
},
|
||||
target: '',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
: []),
|
||||
],
|
||||
type: `synthetics/${monitorType}`,
|
||||
use_output: 'default',
|
||||
|
@ -95,6 +147,11 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
|
|||
host,
|
||||
});
|
||||
|
||||
const generateBrowserConfig = (config: Record<string, string>): Record<string, string> => ({
|
||||
...basicConfig,
|
||||
...config,
|
||||
});
|
||||
|
||||
describe('displays custom UI', () => {
|
||||
before(async () => {
|
||||
const version = await uptimeService.syntheticsPackage.getSyntheticsPackageVersion();
|
||||
|
@ -439,6 +496,137 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
|
|||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('allows saving browser monitor', async () => {
|
||||
// This test ensures that updates made to the Synthetics Policy are carried all the way through
|
||||
// to the generated Agent Policy that is dispatch down to the Elastic Agent.
|
||||
const config = generateBrowserConfig({
|
||||
zipUrl: 'http://test.zip',
|
||||
params: JSON.stringify({ url: 'http://localhost:8080' }),
|
||||
folder: 'folder',
|
||||
username: 'username',
|
||||
password: 'password',
|
||||
});
|
||||
|
||||
await uptimePage.syntheticsIntegration.createBasicBrowserMonitorDetails(config);
|
||||
await uptimePage.syntheticsIntegration.confirmAndSave();
|
||||
|
||||
await uptimePage.syntheticsIntegration.isPolicyCreatedSuccessfully();
|
||||
|
||||
const [agentPolicy] = await uptimeService.syntheticsPackage.getAgentPolicyList();
|
||||
const agentPolicyId = agentPolicy.id;
|
||||
const agentFullPolicy = await uptimeService.syntheticsPackage.getFullAgentPolicy(
|
||||
agentPolicyId
|
||||
);
|
||||
|
||||
expect(getSyntheticsPolicy(agentFullPolicy)).to.eql(
|
||||
generatePolicy({
|
||||
agentFullPolicy,
|
||||
version,
|
||||
name: monitorName,
|
||||
monitorType: 'browser',
|
||||
config: {
|
||||
screenshots: 'on',
|
||||
schedule: '@every 3m',
|
||||
timeout: '16s',
|
||||
tags: [config.tags],
|
||||
'service.name': config.apmServiceName,
|
||||
'source.zip_url.url': config.zipUrl,
|
||||
'source.zip_url.folder': config.folder,
|
||||
'source.zip_url.username': config.username,
|
||||
'source.zip_url.password': config.password,
|
||||
params: JSON.parse(config.params),
|
||||
},
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('allows saving browser monitor with inline script', async () => {
|
||||
// This test ensures that updates made to the Synthetics Policy are carried all the way through
|
||||
// to the generated Agent Policy that is dispatch down to the Elastic Agent.
|
||||
const config = generateBrowserConfig({
|
||||
inlineScript:
|
||||
'step("load homepage", async () => { await page.goto(\'https://www.elastic.co\'); });',
|
||||
});
|
||||
|
||||
await uptimePage.syntheticsIntegration.createBasicBrowserMonitorDetails(config, true);
|
||||
await uptimePage.syntheticsIntegration.confirmAndSave();
|
||||
|
||||
await uptimePage.syntheticsIntegration.isPolicyCreatedSuccessfully();
|
||||
|
||||
const [agentPolicy] = await uptimeService.syntheticsPackage.getAgentPolicyList();
|
||||
const agentPolicyId = agentPolicy.id;
|
||||
const agentFullPolicy = await uptimeService.syntheticsPackage.getFullAgentPolicy(
|
||||
agentPolicyId
|
||||
);
|
||||
|
||||
expect(getSyntheticsPolicy(agentFullPolicy)).to.eql(
|
||||
generatePolicy({
|
||||
agentFullPolicy,
|
||||
version,
|
||||
name: monitorName,
|
||||
monitorType: 'browser',
|
||||
config: {
|
||||
screenshots: 'on',
|
||||
schedule: '@every 3m',
|
||||
timeout: '16s',
|
||||
tags: [config.tags],
|
||||
'service.name': config.apmServiceName,
|
||||
'source.inline.script': config.inlineScript,
|
||||
},
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('allows saving browser monitor advanced options', async () => {
|
||||
// This test ensures that updates made to the Synthetics Policy are carried all the way through
|
||||
// to the generated Agent Policy that is dispatch down to the Elastic Agent.
|
||||
const config = generateBrowserConfig({
|
||||
zipUrl: 'http://test.zip',
|
||||
params: JSON.stringify({ url: 'http://localhost:8080' }),
|
||||
folder: 'folder',
|
||||
username: 'username',
|
||||
password: 'password',
|
||||
});
|
||||
const advancedConfig = {
|
||||
screenshots: 'off',
|
||||
syntheticsArgs: '-ssBlocks',
|
||||
};
|
||||
|
||||
await uptimePage.syntheticsIntegration.createBasicBrowserMonitorDetails(config);
|
||||
await uptimePage.syntheticsIntegration.configureBrowserAdvancedOptions(advancedConfig);
|
||||
await uptimePage.syntheticsIntegration.confirmAndSave();
|
||||
|
||||
await uptimePage.syntheticsIntegration.isPolicyCreatedSuccessfully();
|
||||
|
||||
const [agentPolicy] = await uptimeService.syntheticsPackage.getAgentPolicyList();
|
||||
const agentPolicyId = agentPolicy.id;
|
||||
const agentFullPolicy = await uptimeService.syntheticsPackage.getFullAgentPolicy(
|
||||
agentPolicyId
|
||||
);
|
||||
|
||||
expect(getSyntheticsPolicy(agentFullPolicy)).to.eql(
|
||||
generatePolicy({
|
||||
agentFullPolicy,
|
||||
version,
|
||||
name: monitorName,
|
||||
monitorType: 'browser',
|
||||
config: {
|
||||
screenshots: advancedConfig.screenshots,
|
||||
schedule: '@every 3m',
|
||||
timeout: '16s',
|
||||
tags: [config.tags],
|
||||
'service.name': config.apmServiceName,
|
||||
'source.zip_url.url': config.zipUrl,
|
||||
'source.zip_url.folder': config.folder,
|
||||
'source.zip_url.username': config.username,
|
||||
'source.zip_url.password': config.password,
|
||||
params: JSON.parse(config.params),
|
||||
synthetics_args: [advancedConfig.syntheticsArgs],
|
||||
},
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -205,6 +205,16 @@ export function SyntheticsIntegrationPageProvider({
|
|||
*/
|
||||
async configureRequestBody(testSubj: string, value: string) {
|
||||
await testSubjects.click(`syntheticsRequestBodyTab__${testSubj}`);
|
||||
await this.fillCodeEditor(value);
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* Fills the monaco code editor
|
||||
* @params value {string} value of code input
|
||||
*
|
||||
*/
|
||||
async fillCodeEditor(value: string) {
|
||||
const codeEditorContainer = await testSubjects.find('codeEditorContainer');
|
||||
const textArea = await codeEditorContainer.findByCssSelector('textarea');
|
||||
await textArea.clearValue();
|
||||
|
@ -273,6 +283,40 @@ export function SyntheticsIntegrationPageProvider({
|
|||
await this.fillTextInputByTestSubj('syntheticsICMPHostField', host);
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates a basic browser monitor
|
||||
* @params name {string} the name of the monitor
|
||||
* @params zipUrl {string} the zip url of the synthetics suites
|
||||
*/
|
||||
async createBasicBrowserMonitorDetails(
|
||||
{
|
||||
name,
|
||||
inlineScript,
|
||||
zipUrl,
|
||||
folder,
|
||||
params,
|
||||
username,
|
||||
password,
|
||||
apmServiceName,
|
||||
tags,
|
||||
}: Record<string, string>,
|
||||
isInline: boolean = false
|
||||
) {
|
||||
await this.selectMonitorType('browser');
|
||||
await this.fillTextInputByTestSubj('packagePolicyNameInput', name);
|
||||
await this.createBasicMonitorDetails({ name, apmServiceName, tags });
|
||||
if (isInline) {
|
||||
await testSubjects.click('syntheticsSourceTab__inline');
|
||||
await this.fillCodeEditor(inlineScript);
|
||||
return;
|
||||
}
|
||||
await this.fillTextInputByTestSubj('syntheticsBrowserZipUrl', zipUrl);
|
||||
await this.fillTextInputByTestSubj('syntheticsBrowserZipUrlFolder', folder);
|
||||
await this.fillTextInputByTestSubj('syntheticsBrowserZipUrlUsername', username);
|
||||
await this.fillTextInputByTestSubj('syntheticsBrowserZipUrlPassword', password);
|
||||
await this.fillCodeEditor(params);
|
||||
},
|
||||
|
||||
/**
|
||||
* Enables TLS
|
||||
*/
|
||||
|
@ -376,5 +420,16 @@ export function SyntheticsIntegrationPageProvider({
|
|||
await label.click();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Configure browser advanced settings
|
||||
* @params name {string} the name of the monitor
|
||||
* @params zipUrl {string} the zip url of the synthetics suites
|
||||
*/
|
||||
async configureBrowserAdvancedOptions({ screenshots, syntheticsArgs }: Record<string, string>) {
|
||||
await testSubjects.click('syntheticsBrowserAdvancedFieldsAccordion');
|
||||
await testSubjects.selectValue('syntheticsBrowserScreenshots', screenshots);
|
||||
await this.setComboBox('syntheticsBrowserSyntheticsArgs', syntheticsArgs);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue