diff --git a/playwright/Customizations/Filesystem.spec.ts b/playwright/Customizations/Filesystem.spec.ts index 3f5dd072..4fc4829d 100644 --- a/playwright/Customizations/Filesystem.spec.ts +++ b/playwright/Customizations/Filesystem.spec.ts @@ -4,6 +4,7 @@ import { v4 as uuidv4 } from 'uuid'; import { FILE_SYSTEM_CUSTOMIZATION_URL } from '../../src/constants'; import { test } from '../fixtures/cleanup'; import { isHosted } from '../helpers/helpers'; +import { ensureAuthenticated } from '../helpers/login'; import { navigateToOptionalSteps, ibFrame, @@ -28,6 +29,8 @@ test('Create a blueprint with Filesystem customization', async ({ // Delete the blueprint after the run fixture await cleanup.add(() => deleteBlueprint(page, blueprintName)); + await ensureAuthenticated(page); + // Login, navigate to IB and get the frame await navigateToLandingPage(page); const frame = await ibFrame(page); diff --git a/playwright/Customizations/Firewall.spec.ts b/playwright/Customizations/Firewall.spec.ts index ba909e7c..3748a451 100644 --- a/playwright/Customizations/Firewall.spec.ts +++ b/playwright/Customizations/Firewall.spec.ts @@ -3,6 +3,7 @@ import { v4 as uuidv4 } from 'uuid'; import { test } from '../fixtures/customizations'; import { isHosted } from '../helpers/helpers'; +import { ensureAuthenticated } from '../helpers/login'; import { navigateToOptionalSteps, ibFrame, @@ -27,6 +28,8 @@ test('Create a blueprint with Firewall customization', async ({ // 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); diff --git a/playwright/Customizations/Hostname.spec.ts b/playwright/Customizations/Hostname.spec.ts index dff4e848..2a0779cf 100644 --- a/playwright/Customizations/Hostname.spec.ts +++ b/playwright/Customizations/Hostname.spec.ts @@ -3,6 +3,7 @@ import { v4 as uuidv4 } from 'uuid'; import { test } from '../fixtures/customizations'; import { isHosted } from '../helpers/helpers'; +import { ensureAuthenticated } from '../helpers/login'; import { navigateToOptionalSteps, ibFrame, @@ -28,6 +29,8 @@ test('Create a blueprint with Hostname customization', async ({ // 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); diff --git a/playwright/Customizations/Kernel.spec.ts b/playwright/Customizations/Kernel.spec.ts index 89bbc5dd..e42d0047 100644 --- a/playwright/Customizations/Kernel.spec.ts +++ b/playwright/Customizations/Kernel.spec.ts @@ -3,6 +3,7 @@ import { v4 as uuidv4 } from 'uuid'; import { test } from '../fixtures/customizations'; import { isHosted } from '../helpers/helpers'; +import { ensureAuthenticated } from '../helpers/login'; import { navigateToOptionalSteps, ibFrame, @@ -27,6 +28,8 @@ test('Create a blueprint with Kernel customization', async ({ // 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); diff --git a/playwright/Customizations/Locale.spec.ts b/playwright/Customizations/Locale.spec.ts index a4d9f292..9f0bfe1a 100644 --- a/playwright/Customizations/Locale.spec.ts +++ b/playwright/Customizations/Locale.spec.ts @@ -3,6 +3,7 @@ import { v4 as uuidv4 } from 'uuid'; import { test } from '../fixtures/customizations'; import { isHosted } from '../helpers/helpers'; +import { ensureAuthenticated } from '../helpers/login'; import { navigateToOptionalSteps, ibFrame, @@ -27,6 +28,8 @@ test('Create a blueprint with Locale customization', async ({ // 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); diff --git a/playwright/Customizations/Systemd.spec.ts b/playwright/Customizations/Systemd.spec.ts index 499703eb..bbd1b3cc 100644 --- a/playwright/Customizations/Systemd.spec.ts +++ b/playwright/Customizations/Systemd.spec.ts @@ -3,6 +3,7 @@ import { v4 as uuidv4 } from 'uuid'; import { test } from '../fixtures/customizations'; import { isHosted } from '../helpers/helpers'; +import { ensureAuthenticated } from '../helpers/login'; import { navigateToOptionalSteps, ibFrame, @@ -27,6 +28,8 @@ test('Create a blueprint with Systemd customization', async ({ // 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); diff --git a/playwright/Customizations/Timezone.spec.ts b/playwright/Customizations/Timezone.spec.ts index 403d6ef9..4d2de9f9 100644 --- a/playwright/Customizations/Timezone.spec.ts +++ b/playwright/Customizations/Timezone.spec.ts @@ -3,6 +3,7 @@ import { v4 as uuidv4 } from 'uuid'; import { test } from '../fixtures/customizations'; import { isHosted } from '../helpers/helpers'; +import { ensureAuthenticated } from '../helpers/login'; import { navigateToOptionalSteps, ibFrame, @@ -27,6 +28,8 @@ test('Create a blueprint with Timezone customization', async ({ // 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); diff --git a/playwright/helpers/login.ts b/playwright/helpers/login.ts index a52d4ce2..56e3d7cc 100644 --- a/playwright/helpers/login.ts +++ b/playwright/helpers/login.ts @@ -23,6 +23,38 @@ export const login = async (page: Page) => { return loginCockpit(page, user, password); }; +/** + * Checks if the user is already authenticated, if not, logs them in + * @param page - the page object + */ +export const ensureAuthenticated = async (page: Page) => { + // Navigate to the target page + if (isHosted()) { + await page.goto('/insights/image-builder/landing'); + } else { + await page.goto('/cockpit-image-builder'); + } + + // Check for authentication success indicator + const successIndicator = isHosted() + ? page.getByRole('heading', { name: 'All images' }) + : ibFrame(page).getByRole('heading', { name: 'All images' }); + + let isAuthenticated = false; + try { + // Give it a 30 second period to load, it's less expensive than having to rerun the test + await expect(successIndicator).toBeVisible({ timeout: 30000 }); + isAuthenticated = true; + } catch { + isAuthenticated = false; + } + + if (!isAuthenticated) { + // Not authenticated, need to login + await login(page); + } +}; + const loginCockpit = async (page: Page, user: string, password: string) => { await page.goto('/cockpit-image-builder'); @@ -33,26 +65,36 @@ const loginCockpit = async (page: Page, user: string, password: string) => { // image-builder lives inside an iframe const frame = ibFrame(page); - // cockpit-image-builder needs superuser, expect an error message - // when the user does not have admin priviliges - await expect( - frame.getByRole('heading', { name: 'Access is limited' }) - ).toBeVisible(); - await page.getByRole('button', { name: 'Limited access' }).click(); + try { + // Check if the user already has administrative access + await expect( + page.getByRole('button', { name: 'Administrative access' }) + ).toBeVisible(); + } catch { + // If not, try to gain it + // cockpit-image-builder needs superuser, expect an error message + // when the user does not have admin priviliges + await expect( + frame.getByRole('heading', { name: 'Access is limited' }) + ).toBeVisible(); + await page.getByRole('button', { name: 'Limited access' }).click(); - // different popup opens based on type of account (can be passwordless) - const authenticateButton = page.getByRole('button', { name: 'Authenticate' }); - const closeButton = page.getByText('Close'); - await expect(authenticateButton.or(closeButton)).toBeVisible(); + // different popup opens based on type of account (can be passwordless) + const authenticateButton = page.getByRole('button', { + name: 'Authenticate', + }); + const closeButton = page.getByText('Close'); + await expect(authenticateButton.or(closeButton)).toBeVisible(); - if (await authenticateButton.isVisible()) { - // with password - await page.getByRole('textbox', { name: 'Password' }).fill(password); - await authenticateButton.click(); - } - if (await closeButton.isVisible()) { - // passwordless - await closeButton.click(); + if (await authenticateButton.isVisible()) { + // with password + await page.getByRole('textbox', { name: 'Password' }).fill(password); + await authenticateButton.click(); + } + if (await closeButton.isVisible()) { + // passwordless + await closeButton.click(); + } } // expect to have administrative access @@ -81,9 +123,18 @@ 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 - }`; + if (isHosted()) { + // For hosted service, look for cs_jwt token + process.env.TOKEN = `Bearer ${ + cookies.find((cookie) => cookie.name === 'cs_jwt')?.value + }`; + } else { + // For Cockpit, we don't need a TOKEN but we can still store it for consistency + const cockpitCookie = cookies.find((cookie) => cookie.name === 'cockpit'); + if (cockpitCookie) { + process.env.TOKEN = cockpitCookie.value; + } + } // eslint-disable-next-line playwright/no-wait-for-timeout await page.waitForTimeout(100); }; diff --git a/playwright/test.spec.ts b/playwright/test.spec.ts index c20fc087..3739074a 100644 --- a/playwright/test.spec.ts +++ b/playwright/test.spec.ts @@ -2,11 +2,13 @@ import { expect, test } from '@playwright/test'; import { v4 as uuidv4 } from 'uuid'; import { closePopupsIfExist, isHosted } from './helpers/helpers'; +import { ensureAuthenticated } from './helpers/login'; import { ibFrame, navigateToLandingPage } from './helpers/navHelpers'; test.describe.serial('test', () => { const blueprintName = uuidv4(); test('create blueprint', async ({ page }) => { + await ensureAuthenticated(page); await closePopupsIfExist(page); // Navigate to IB landing page and get the frame await navigateToLandingPage(page); @@ -85,6 +87,7 @@ test.describe.serial('test', () => { }); test('edit blueprint', async ({ page }) => { + await ensureAuthenticated(page); await closePopupsIfExist(page); // package searching is really slow the first time in cockpit if (!isHosted()) { @@ -123,6 +126,7 @@ test.describe.serial('test', () => { }); test('build blueprint', async ({ page }) => { + await ensureAuthenticated(page); await closePopupsIfExist(page); // Navigate to IB landing page and get the frame await navigateToLandingPage(page); @@ -142,6 +146,7 @@ test.describe.serial('test', () => { }); test('delete blueprint', async ({ page }) => { + await ensureAuthenticated(page); await closePopupsIfExist(page); // Navigate to IB landing page and get the frame await navigateToLandingPage(page);