playwright: Add single login for all tests

Add a single login for all tests in the form of a global setup. This commit also removes the login from all tests and replaces it with navigation to landing page and revamps the popup closing logic from being applied in logging step  into a separate fixture.
This commit is contained in:
Tom Koscielniak 2025-06-19 11:46:39 +02:00 committed by Klara Simickova
parent 78bb1e118b
commit b499dfcf93
14 changed files with 124 additions and 39 deletions

1
.gitignore vendored
View file

@ -48,3 +48,4 @@ rpmbuild
/blob-report/
/playwright/.cache/
.env
.auth

View file

@ -34,9 +34,14 @@ export default defineConfig({
ignoreHTTPSErrors: true,
},
projects: [
{ name: 'setup', testMatch: /.*\.setup\.ts/ },
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
use: {
...devices['Desktop Chrome'],
storageState: '.auth/user.json',
},
dependencies: ['setup'],
},
],
});

View file

@ -1,10 +1,13 @@
import { expect } from '@playwright/test';
import { v4 as uuidv4 } from 'uuid';
import { test } from '../fixtures/cleanup';
import { test } from '../fixtures/customizations';
import { isHosted } from '../helpers/helpers';
import { login } from '../helpers/login';
import { navigateToOptionalSteps, ibFrame } from '../helpers/navHelpers';
import {
navigateToOptionalSteps,
ibFrame,
navigateToLandingPage,
} from '../helpers/navHelpers';
import {
registerLater,
fillInDetails,
@ -24,8 +27,8 @@ test('Create a blueprint with Firewall customization', async ({
// Delete the blueprint after the run fixture
await cleanup.add(() => deleteBlueprint(page, blueprintName));
// Login, navigate to IB and get the frame
await login(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 () => {

View file

@ -1,10 +1,13 @@
import { expect } from '@playwright/test';
import { v4 as uuidv4 } from 'uuid';
import { test } from '../fixtures/cleanup';
import { test } from '../fixtures/customizations';
import { isHosted } from '../helpers/helpers';
import { login } from '../helpers/login';
import { navigateToOptionalSteps, ibFrame } from '../helpers/navHelpers';
import {
navigateToOptionalSteps,
ibFrame,
navigateToLandingPage,
} from '../helpers/navHelpers';
import {
registerLater,
fillInDetails,
@ -25,8 +28,8 @@ test('Create a blueprint with Hostname customization', async ({
// Delete the blueprint after the run fixture
await cleanup.add(() => deleteBlueprint(page, blueprintName));
// Login, navigate to IB and get the frame
await login(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 () => {

View file

@ -1,10 +1,13 @@
import { expect } from '@playwright/test';
import { v4 as uuidv4 } from 'uuid';
import { test } from '../fixtures/cleanup';
import { test } from '../fixtures/customizations';
import { isHosted } from '../helpers/helpers';
import { login } from '../helpers/login';
import { navigateToOptionalSteps, ibFrame } from '../helpers/navHelpers';
import {
navigateToOptionalSteps,
ibFrame,
navigateToLandingPage,
} from '../helpers/navHelpers';
import {
registerLater,
fillInDetails,
@ -24,8 +27,8 @@ test('Create a blueprint with Kernel customization', async ({
// Delete the blueprint after the run fixture
await cleanup.add(() => deleteBlueprint(page, blueprintName));
// Login, navigate to IB and get the frame
await login(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 () => {

View file

@ -1,10 +1,13 @@
import { expect } from '@playwright/test';
import { v4 as uuidv4 } from 'uuid';
import { test } from '../fixtures/cleanup';
import { test } from '../fixtures/customizations';
import { isHosted } from '../helpers/helpers';
import { login } from '../helpers/login';
import { navigateToOptionalSteps, ibFrame } from '../helpers/navHelpers';
import {
navigateToOptionalSteps,
ibFrame,
navigateToLandingPage,
} from '../helpers/navHelpers';
import {
registerLater,
fillInDetails,
@ -24,8 +27,8 @@ test('Create a blueprint with Locale customization', async ({
// Delete the blueprint after the run fixture
await cleanup.add(() => deleteBlueprint(page, blueprintName));
// Login, navigate to IB and get the frame
await login(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 () => {

View file

@ -1,10 +1,13 @@
import { expect } from '@playwright/test';
import { v4 as uuidv4 } from 'uuid';
import { test } from '../fixtures/cleanup';
import { test } from '../fixtures/customizations';
import { isHosted } from '../helpers/helpers';
import { login } from '../helpers/login';
import { navigateToOptionalSteps, ibFrame } from '../helpers/navHelpers';
import {
navigateToOptionalSteps,
ibFrame,
navigateToLandingPage,
} from '../helpers/navHelpers';
import {
registerLater,
fillInDetails,
@ -24,8 +27,8 @@ test('Create a blueprint with Systemd customization', async ({
// Delete the blueprint after the run fixture
await cleanup.add(() => deleteBlueprint(page, blueprintName));
// Login, navigate to IB and get the frame
await login(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 () => {

View file

@ -1,10 +1,13 @@
import { expect } from '@playwright/test';
import { v4 as uuidv4 } from 'uuid';
import { test } from '../fixtures/cleanup';
import { test } from '../fixtures/customizations';
import { isHosted } from '../helpers/helpers';
import { login } from '../helpers/login';
import { navigateToOptionalSteps, ibFrame } from '../helpers/navHelpers';
import {
navigateToOptionalSteps,
ibFrame,
navigateToLandingPage,
} from '../helpers/navHelpers';
import {
registerLater,
fillInDetails,
@ -24,8 +27,8 @@ test('Create a blueprint with Timezone customization', async ({
// Delete the blueprint after the run fixture
await cleanup.add(() => deleteBlueprint(page, blueprintName));
// Login, navigate to IB and get the frame
await login(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 () => {

View file

@ -0,0 +1,8 @@
// This is a common fixture for the customizations tests
import { mergeTests } from '@playwright/test';
import { test as cleanupTest } from './cleanup';
import { test as popupTest } from './popupHandler';
// Combine the fixtures into one
export const test = mergeTests(cleanupTest, popupTest);

View file

@ -0,0 +1,19 @@
import { test as base } from '@playwright/test';
import { closePopupsIfExist } from '../helpers/helpers';
export interface PopupHandlerFixture {
popupHandler: void;
}
// This fixture will close any popups that might get opened during the test execution
export const test = base.extend<PopupHandlerFixture>({
popupHandler: [
async ({ page }, use) => {
await closePopupsIfExist(page);
// eslint-disable-next-line react-hooks/rules-of-hooks
await use(undefined);
},
{ auto: true },
],
});

View file

@ -0,0 +1,12 @@
import { test as setup } from '@playwright/test';
import { login, storeStorageStateAndToken } from './helpers/login';
setup.describe('Setup', () => {
setup.describe.configure({ retries: 3 });
setup('Authenticate', async ({ page }) => {
await login(page);
await storeStorageStateAndToken(page);
});
});

View file

@ -1,3 +1,5 @@
import path from 'path';
import { type Page, expect } from '@playwright/test';
import { closePopupsIfExist, isHosted, togglePreview } from './helpers';
@ -74,3 +76,14 @@ const loginConsole = async (page: Page, user: string, password: string) => {
await togglePreview(page);
await expect(page.getByRole('heading', { name: 'All images' })).toBeVisible();
};
export const storeStorageStateAndToken = async (page: Page) => {
const { cookies } = await page
.context()
.storageState({ path: path.join(__dirname, '../../.auth/user.json') });
process.env.TOKEN = `Bearer ${
cookies.find((cookie) => cookie.name === 'cs_jwt')?.value
}`;
// eslint-disable-next-line playwright/no-wait-for-timeout
await page.waitForTimeout(100);
};

View file

@ -1,6 +1,6 @@
import { expect, FrameLocator, type Page, test } from '@playwright/test';
import { isHosted } from './helpers';
import { closePopupsIfExist, isHosted } from './helpers';
import { ibFrame, navigateToLandingPage } from './navHelpers';
/**
@ -70,6 +70,8 @@ export const fillInImageOutputGuest = async (page: Page | FrameLocator) => {
* @param blueprintName - the name of the blueprint to delete
*/
export const deleteBlueprint = async (page: Page, blueprintName: string) => {
// Since new browser is opened during the BP cleanup, we need to call the popup closer again
await closePopupsIfExist(page);
await test.step(
'Delete the blueprint with name: ' + blueprintName,
async () => {

View file

@ -1,14 +1,15 @@
import { expect, test } from '@playwright/test';
import { v4 as uuidv4 } from 'uuid';
import { isHosted } from './helpers/helpers';
import { login } from './helpers/login';
import { ibFrame } from './helpers/navHelpers';
import { closePopupsIfExist, isHosted } from './helpers/helpers';
import { ibFrame, navigateToLandingPage } from './helpers/navHelpers';
test.describe.serial('test', () => {
const blueprintName = uuidv4();
test('create blueprint', async ({ page }) => {
await login(page);
await closePopupsIfExist(page);
// Navigate to IB landing page and get the frame
await navigateToLandingPage(page);
const frame = await ibFrame(page);
frame.getByRole('heading', { name: 'Images About image builder' });
@ -84,12 +85,14 @@ test.describe.serial('test', () => {
});
test('edit blueprint', async ({ page }) => {
await closePopupsIfExist(page);
// package searching is really slow the first time in cockpit
if (!isHosted()) {
test.setTimeout(300000);
}
await login(page);
// Navigate to IB landing page and get the frame
await navigateToLandingPage(page);
const frame = await ibFrame(page);
await frame
.getByRole('textbox', { name: 'Search input' })
@ -120,7 +123,9 @@ test.describe.serial('test', () => {
});
test('build blueprint', async ({ page }) => {
await login(page);
await closePopupsIfExist(page);
// Navigate to IB landing page and get the frame
await navigateToLandingPage(page);
const frame = await ibFrame(page);
await frame
.getByRole('textbox', { name: 'Search input' })
@ -137,7 +142,9 @@ test.describe.serial('test', () => {
});
test('delete blueprint', async ({ page }) => {
await login(page);
await closePopupsIfExist(page);
// Navigate to IB landing page and get the frame
await navigateToLandingPage(page);
const frame = await ibFrame(page);
await frame
.getByRole('textbox', { name: 'Search input' })