214 lines
7.5 KiB
TypeScript
214 lines
7.5 KiB
TypeScript
import { expect } from '@playwright/test';
|
|
import { v4 as uuidv4 } from 'uuid';
|
|
|
|
import { test } from '../fixtures/customizations';
|
|
import { isHosted } from '../helpers/helpers';
|
|
import { ensureAuthenticated } from '../helpers/login';
|
|
import {
|
|
ibFrame,
|
|
navigateToLandingPage,
|
|
navigateToOptionalSteps,
|
|
} from '../helpers/navHelpers';
|
|
import {
|
|
createBlueprint,
|
|
deleteBlueprint,
|
|
exportBlueprint,
|
|
fillInDetails,
|
|
fillInImageOutputGuest,
|
|
importBlueprint,
|
|
registerLater,
|
|
} from '../helpers/wizardHelpers';
|
|
|
|
const validCallbackUrl =
|
|
'https://controller.url/api/controller/v2/job_templates/9/callback/';
|
|
const validHttpCallbackUrl =
|
|
'http://controller.url/api/controller/v2/job_templates/9/callback/';
|
|
const validHostConfigKey = 'hostconfigkey';
|
|
const validCertificate = `-----BEGIN CERTIFICATE-----
|
|
MIIDXTCCAkWgAwIBAgIJAOEzx5ezZ9EIMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
|
|
BAYTAklOMQswCQYDVQQIDAJLUjEMMAoGA1UEBwwDS1JHMRAwDgYDVQQKDAdUZXN0
|
|
IENBMB4XDTI1MDUxNTEyMDAwMFoXDTI2MDUxNTEyMDAwMFowRTELMAkGA1UEBhMC
|
|
SU4xCzAJBgNVBAgMAktSMQwwCgYDVQQHDANSR0sxEDAOBgNVBAoMB1Rlc3QgQ0Ew
|
|
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC+R4gfN5pyJQo5qBTTtN+7
|
|
eE9CSXZJ8SVVaE3U54IgqQoqsSoBY5QtExy7v5C6l6mW4E6dzK/JecmvTTO/BvlG
|
|
A5k2hxB6bOQxtxYwfgElH+RFWN9P4xxhtEiQgHoG1rDfnXuDJk1U3YEkCQELUebz
|
|
fF3EIDU1yR0Sz2bA+Sl2VXe8og1MEZfytq8VZUVltxtn2PfW7zI5gOllBR2sKeUc
|
|
K6h8HXN7qMgfEvsLIXxTw7fU/zA3ibcxfRCl3m6QhF8hwRh6F9Wtz2s8hCzGegV5
|
|
z0M39nY7X8C3GZQ4Ly8v8DdY+FbEix7K3SSBRbWtdPfAHRFlX9Er2Wf8DAr7O2hH
|
|
AgMBAAGjUDBOMB0GA1UdDgQWBBTXXz2eIDgK+BhzDUAGzptn0OMcpDAfBgNVHSME
|
|
GDAWgBTXXz2eIDgK+BhzDUAGzptn0OMcpDAMBgNVHRMEBTADAQH/MA0GCSqGSIb3
|
|
DQEBCwUAA4IBAQAoUgY4jsuBMB3el9cc7JS2rcOhhJzn47Hj2UANfJq52g5lbjo7
|
|
XDc7Wb3VDcV+1LzjdzayT1qO1WzHb6FDPW9L9f6h4s8lj6MvJ+xhOWgD11srdIt3
|
|
vbQaQW4zDfeVRcKXzqbcUX8BLXAdzJPqVwZ+Z4EDjYrJ7lF9k+IqfZm0MsYX7el9
|
|
kvdRHbLuF4Q0sZ05CXMFkhM0Ulhu4MZ+1FcsQa7nWfZzTmbjHOuWJPB4z5WwrB7z
|
|
U8YYvWJ3qxToWGbATqJxkRKGGqLrNrmwcfzgPqkpuCRYi0Kky6gJ1RvL+DRopY9x
|
|
uD+ckf3oH2wYAB6RpPRMkfVxe7lGMvq/yEZ6
|
|
-----END CERTIFICATE-----`;
|
|
const invalidCertificate = `-----BEGIN CERTIFICATE-----
|
|
ThisIs*Not+Valid/Base64==
|
|
-----END CERTIFICATE-----`;
|
|
|
|
test('Create a blueprint with AAP registration customization', async ({
|
|
page,
|
|
cleanup,
|
|
}) => {
|
|
const blueprintName = 'test-' + uuidv4();
|
|
|
|
// Skip entirely in Cockpit/on-premise where AAP customization is unavailable
|
|
test.skip(!isHosted(), 'AAP customization is not available in the plugin');
|
|
|
|
// Delete the blueprint after the run fixture
|
|
await cleanup.add(() => deleteBlueprint(page, blueprintName));
|
|
await ensureAuthenticated(page);
|
|
|
|
// Navigate to IB landing page and get the frame
|
|
await navigateToLandingPage(page);
|
|
const frame = await ibFrame(page);
|
|
|
|
await test.step('Navigate to optional steps in Wizard', async () => {
|
|
await navigateToOptionalSteps(frame);
|
|
await registerLater(frame);
|
|
});
|
|
|
|
await test.step('Select and fill the AAP step with valid configuration', async () => {
|
|
await frame
|
|
.getByRole('button', { name: 'Ansible Automation Platform' })
|
|
.click();
|
|
await frame
|
|
.getByRole('textbox', { name: 'ansible callback url' })
|
|
.fill(validCallbackUrl);
|
|
await frame
|
|
.getByRole('textbox', { name: 'host config key' })
|
|
.fill(validHostConfigKey);
|
|
await frame
|
|
.getByRole('textbox', { name: 'File upload' })
|
|
.fill(validCertificate);
|
|
await expect(frame.getByRole('button', { name: 'Next' })).toBeEnabled();
|
|
});
|
|
|
|
await test.step('Test TLS confirmation checkbox for HTTPS URLs', async () => {
|
|
// TLS confirmation checkbox should appear for HTTPS URLs
|
|
await expect(
|
|
frame.getByRole('checkbox', {
|
|
name: 'Insecure',
|
|
}),
|
|
).toBeVisible();
|
|
|
|
// Check TLS confirmation and verify CA input is hidden
|
|
await frame
|
|
.getByRole('checkbox', {
|
|
name: 'Insecure',
|
|
})
|
|
.check();
|
|
await expect(
|
|
frame.getByRole('textbox', { name: 'File upload' }),
|
|
).toBeHidden();
|
|
|
|
await frame
|
|
.getByRole('checkbox', {
|
|
name: 'Insecure',
|
|
})
|
|
.uncheck();
|
|
|
|
await expect(
|
|
frame.getByRole('textbox', { name: 'File upload' }),
|
|
).toBeVisible();
|
|
});
|
|
|
|
await test.step('Test certificate validation', async () => {
|
|
await frame.getByRole('textbox', { name: 'File upload' }).clear();
|
|
await frame
|
|
.getByRole('textbox', { name: 'File upload' })
|
|
.fill(invalidCertificate);
|
|
await expect(frame.getByText(/Certificate.*is not valid/)).toBeVisible();
|
|
|
|
await frame.getByRole('textbox', { name: 'File upload' }).clear();
|
|
await frame
|
|
.getByRole('textbox', { name: 'File upload' })
|
|
.fill(validCertificate);
|
|
|
|
await expect(frame.getByText('Certificate was uploaded')).toBeVisible();
|
|
});
|
|
|
|
await test.step('Test HTTP URL behavior', async () => {
|
|
await frame.getByRole('textbox', { name: 'ansible callback url' }).clear();
|
|
await frame
|
|
.getByRole('textbox', { name: 'ansible callback url' })
|
|
.fill(validHttpCallbackUrl);
|
|
|
|
// TLS confirmation checkbox should NOT appear for HTTP URLs
|
|
await expect(
|
|
frame.getByRole('checkbox', {
|
|
name: 'Insecure',
|
|
}),
|
|
).toBeHidden();
|
|
await expect(
|
|
frame.getByRole('textbox', { name: 'File upload' }),
|
|
).toBeVisible();
|
|
|
|
await frame.getByRole('textbox', { name: 'ansible callback url' }).clear();
|
|
await frame
|
|
.getByRole('textbox', { name: 'ansible callback url' })
|
|
.fill(validCallbackUrl);
|
|
});
|
|
|
|
await test.step('Complete AAP configuration and proceed to review', async () => {
|
|
await frame.getByRole('button', { name: 'Review and finish' }).click();
|
|
});
|
|
|
|
await test.step('Fill the BP details', async () => {
|
|
await fillInDetails(frame, blueprintName);
|
|
});
|
|
|
|
await test.step('Create BP', async () => {
|
|
await createBlueprint(frame, blueprintName);
|
|
});
|
|
|
|
await test.step('Edit BP and verify AAP configuration persists', async () => {
|
|
await frame.getByRole('button', { name: 'Edit blueprint' }).click();
|
|
await frame.getByLabel('Revisit Ansible Automation Platform step').click();
|
|
|
|
await expect(
|
|
frame.getByRole('textbox', { name: 'ansible callback url' }),
|
|
).toHaveValue(validCallbackUrl);
|
|
await expect(
|
|
frame.getByRole('textbox', { name: 'host config key' }),
|
|
).toHaveValue(validHostConfigKey);
|
|
await expect(
|
|
frame.getByRole('textbox', { name: 'File upload' }),
|
|
).toHaveValue(validCertificate);
|
|
|
|
await frame.getByRole('button', { name: 'Review and finish' }).click();
|
|
await frame
|
|
.getByRole('button', { name: 'Save changes to blueprint' })
|
|
.click();
|
|
});
|
|
// This is for hosted service only as these features are not available in cockpit plugin
|
|
await test.step('Export BP', async (step) => {
|
|
step.skip(!isHosted(), 'Exporting is not available in the plugin');
|
|
await exportBlueprint(page, blueprintName);
|
|
});
|
|
|
|
await test.step('Import BP', async (step) => {
|
|
step.skip(!isHosted(), 'Importing is not available in the plugin');
|
|
await importBlueprint(page, blueprintName);
|
|
});
|
|
|
|
await test.step('Review imported BP', async (step) => {
|
|
step.skip(!isHosted(), 'Importing is not available in the plugin');
|
|
await fillInImageOutputGuest(page);
|
|
await page
|
|
.getByRole('button', { name: 'Ansible Automation Platform' })
|
|
.click();
|
|
await expect(
|
|
page.getByRole('textbox', { name: 'ansible callback url' }),
|
|
).toHaveValue(validCallbackUrl);
|
|
await expect(
|
|
page.getByRole('textbox', { name: 'host config key' }),
|
|
).toBeEmpty();
|
|
await expect(
|
|
page.getByRole('textbox', { name: 'File upload' }),
|
|
).toHaveValue(validCertificate);
|
|
await page.getByRole('button', { name: 'Cancel' }).click();
|
|
});
|
|
});
|