playwright: adapt tests to hosted
Makes the test's base url, user & password configurable through the environment. Abstracts differences between hosted and cockpit where possible to lib, and adds conditionals otherwise.
This commit is contained in:
parent
f0a3574cda
commit
21ec51a69e
4 changed files with 107 additions and 30 deletions
|
|
@ -1,21 +1,40 @@
|
|||
import { expect, type Page, type FrameLocator } from '@playwright/test';
|
||||
|
||||
export const ibFrame = (page: Page): FrameLocator => {
|
||||
export const ibFrame = (page: Page): FrameLocator | Page => {
|
||||
if (isHosted()) {
|
||||
return page
|
||||
}
|
||||
return page.locator('iframe[name="cockpit1\\:localhost\\/cockpit-image-builder"]').contentFrame();
|
||||
}
|
||||
|
||||
export const loginCockpit = async (
|
||||
page: Page,
|
||||
username?: string,
|
||||
password?: string
|
||||
export const login = async (
|
||||
page: Page
|
||||
) => {
|
||||
if (!username || !password) {
|
||||
throw new Error('Username or password not found');
|
||||
if (!process.env.USER || !process.env.PASSWORD) {
|
||||
throw new Error('user or password not set in environment');
|
||||
}
|
||||
|
||||
const user = process.env.USER;
|
||||
const password = process.env.PASSWORD;
|
||||
|
||||
if (isHosted()) {
|
||||
return loginConsole(page, user, password);
|
||||
}
|
||||
return loginCockpit(page, user, password);
|
||||
}
|
||||
|
||||
export const isHosted = (): Boolean => {
|
||||
return process.env.BASE_URL?.includes('redhat.com') || false;
|
||||
}
|
||||
|
||||
const loginCockpit = async (
|
||||
page: Page,
|
||||
user: string,
|
||||
password: string
|
||||
) => {
|
||||
await page.goto('/cockpit-image-builder');
|
||||
|
||||
await page.getByRole('textbox', { name: 'User name' }).fill(username);
|
||||
await page.getByRole('textbox', { name: 'User name' }).fill(user);
|
||||
await page.getByRole('textbox', { name: 'Password' }).fill(password);
|
||||
|
||||
// cockpit-image-builder needs superuser
|
||||
|
|
@ -24,3 +43,33 @@ export const loginCockpit = async (
|
|||
await page.getByText('Close').click();
|
||||
await page.getByRole('button', { name: 'Administrative access' });
|
||||
};
|
||||
|
||||
const loginConsole = async (
|
||||
page: Page,
|
||||
user: string,
|
||||
password: string
|
||||
) => {
|
||||
await page.goto('/insights/image-builder/landing');
|
||||
await page.getByRole('textbox', { name: 'Red Hat login or email' }).fill(user);
|
||||
await page.getByRole('button', { name: 'Next' }).click();
|
||||
await page.getByRole('textbox', { name: 'Password' }).fill(password);
|
||||
await page.getByRole('button', { name: 'Log in' }).click();
|
||||
await closePopupsIfExist(page);
|
||||
await page.locator('#preview-toggle').check();
|
||||
await page.getByRole('heading', { name: 'All images' });
|
||||
}
|
||||
|
||||
const closePopupsIfExist = async (page: Page) => {
|
||||
const locatorsToCheck = [
|
||||
page.locator('.pf-v5-c-alert.notification-item button'), // This closes all toast pop-ups
|
||||
page.locator(`button[id^="pendo-close-guide-"]`), // This closes the pendo guide pop-up
|
||||
page.locator(`button[id="truste-consent-button"]`), // This closes the trusted consent pop-up
|
||||
page.getByLabel('close-notification'), // This closes a one off info notification (May be covered by the toast above, needs recheck.)
|
||||
];
|
||||
|
||||
for (const locator of locatorsToCheck) {
|
||||
await page.addLocatorHandler(locator, async () => {
|
||||
await locator.first().click(); // There can be multiple toast pop-ups
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,28 +1,45 @@
|
|||
import { expect, test } from '@playwright/test';
|
||||
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
import {
|
||||
loginCockpit,
|
||||
login,
|
||||
ibFrame,
|
||||
isHosted,
|
||||
} from './lib/lib';
|
||||
|
||||
test.describe('test', () => {
|
||||
test.describe.serial('test', () => {
|
||||
let blueprintName = uuidv4();
|
||||
test('create blueprint', async ({ page }) => {
|
||||
await loginCockpit(page, 'admin', 'foobar');
|
||||
// await enableComposer(page);
|
||||
await login(page)
|
||||
const frame = await ibFrame(page);
|
||||
|
||||
// image output
|
||||
await frame.getByRole('heading', { name: 'Images About image builder' });
|
||||
await frame.getByRole('heading', { name: 'Blueprints' });
|
||||
await frame.getByRole('heading', { name: 'No blueprints yet' });
|
||||
await frame.getByTestId('create-blueprint-action-emptystate').click();
|
||||
await frame.getByTestId('blueprints-create-button').click();
|
||||
|
||||
await frame.getByRole('heading', { name: 'Image output' });
|
||||
await frame.getByTestId('checkbox-guest-image').click();
|
||||
await frame.getByRole('button', { name: 'Next', exact: true }).click();
|
||||
|
||||
if (isHosted()) {
|
||||
await frame.getByRole('heading', { name: 'Register systems using this image' });
|
||||
await page.getByTestId('automatically-register-checkbox').uncheck();
|
||||
await frame.getByRole('button', { name: 'Next', exact: true }).click();
|
||||
await frame.getByRole('heading', { name: 'Compliance' });
|
||||
await frame.getByRole('button', { name: 'Next', exact: true }).click();
|
||||
}
|
||||
|
||||
await frame.getByRole('heading', { name: 'File system configuration' });
|
||||
await frame.getByRole('button', { name: 'Next', exact: true }).click();
|
||||
|
||||
if (isHosted()) {
|
||||
await frame.getByRole('heading', { name: 'Repository snapshot' });
|
||||
await frame.getByRole('button', { name: 'Next', exact: true }).click();
|
||||
await frame.getByRole('heading', { name: 'Custom repositories' });
|
||||
await frame.getByRole('button', { name: 'Next', exact: true }).click();
|
||||
}
|
||||
|
||||
await frame.getByRole('heading', { name: 'Additional packages' });
|
||||
await frame.getByRole('button', { name: 'Next', exact: true }).click();
|
||||
|
||||
|
|
@ -47,25 +64,33 @@ test.describe('test', () => {
|
|||
await frame.getByRole('heading', { name: 'Systemd services' });
|
||||
await frame.getByRole('button', { name: 'Next', exact: true }).click();
|
||||
|
||||
if (isHosted()) {
|
||||
await frame.getByRole('heading', { name: 'First boot configuration' });
|
||||
await frame.getByRole('button', { name: 'Next', exact: true }).click();
|
||||
}
|
||||
|
||||
await frame.getByRole('heading', { name: 'Details' });
|
||||
await frame.getByTestId('blueprint').fill('test-blueprint');
|
||||
await expect(frame.getByTestId('blueprint')).toHaveValue('test-blueprint');
|
||||
await frame.getByTestId('blueprint').fill(blueprintName);
|
||||
await expect(frame.getByTestId('blueprint')).toHaveValue(blueprintName);
|
||||
await frame.getByRole('button', { name: 'Next', exact: true }).click();
|
||||
|
||||
await frame.getByRole('button', { name: 'Create blueprint' }).click();
|
||||
await frame.getByTestId('close-button-saveandbuild-modal').click();
|
||||
await frame.getByRole('button', { name: 'Create blueprint' }).click();
|
||||
|
||||
await frame.getByText('test-blueprint');
|
||||
await frame.getByText(blueprintName);
|
||||
});
|
||||
|
||||
test('edit blueprint', async ({ page }) => {
|
||||
// package searching is really slow the first time
|
||||
test.setTimeout(300000)
|
||||
// package searching is really slow the first time in cockpit
|
||||
if (!isHosted()) {
|
||||
test.setTimeout(300000);
|
||||
}
|
||||
|
||||
await loginCockpit(page, 'admin', 'foobar');
|
||||
await login(page);
|
||||
const frame = await ibFrame(page);
|
||||
await frame.getByText('test-blueprint').click();
|
||||
await frame.getByRole('textbox', { name: 'Search input' }).fill(blueprintName);
|
||||
await frame.getByText(blueprintName, { exact: true }).first().click();
|
||||
|
||||
await frame.getByRole('button', { name: 'Edit blueprint' }).click();
|
||||
await frame.getByRole('button', { name: 'Additional packages' }).click();
|
||||
|
|
@ -86,21 +111,22 @@ test.describe('test', () => {
|
|||
});
|
||||
|
||||
test('build blueprint', async ({ page }) => {
|
||||
// add time enough for depsolving
|
||||
test.setTimeout(60 * 1000);
|
||||
await loginCockpit(page, 'admin', 'foobar');
|
||||
await login(page);
|
||||
const frame = await ibFrame(page);
|
||||
await frame.getByText('test-blueprint').click();
|
||||
await frame.getByRole('textbox', { name: 'Search input' }).fill(blueprintName);
|
||||
await frame.getByText(blueprintName, { exact: true }).first().click();
|
||||
await frame.getByTestId('blueprint-build-image-menu-option').click();
|
||||
|
||||
// make sure the image is present
|
||||
await frame.getByTestId('images-table').getByText('Fedora');
|
||||
await frame.getByTestId('images-table').getByRole('button', { name: 'Details' }).click();
|
||||
await frame.getByText('Build Information');
|
||||
});
|
||||
|
||||
test('delete blueprint', async ({ page }) => {
|
||||
await loginCockpit(page, 'admin', 'foobar');
|
||||
await login(page);
|
||||
const frame = await ibFrame(page);
|
||||
await frame.getByText('test-blueprint').click();
|
||||
await frame.getByRole('textbox', { name: 'Search input' }).fill(blueprintName);
|
||||
await frame.getByText(blueprintName, { exact: true }).first().click();
|
||||
await frame.getByTestId('blueprint-action-menu-toggle').click();
|
||||
await frame.getByRole('menuitem', { name: 'Delete blueprint' }).click();
|
||||
await frame.getByRole('button', { name: 'Delete' }).click();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue