diff --git a/platform/main/PlatformAbout.test.tsx b/platform/main/PlatformAbout.test.tsx new file mode 100644 index 0000000000..3d0fd647f8 --- /dev/null +++ b/platform/main/PlatformAbout.test.tsx @@ -0,0 +1,128 @@ +import { + PageDialogProvider, + PageSettingsContext, + usePageDialog, + type IPageSettings, +} from '@ansible/ansible-ui-framework'; +import { awxAPI } from '@ansible/awx-ui/common/api/awx-utils'; +import { render, screen, waitFor, within } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import { edaAPI } from '@ansible/eda-ui/common/eda-utils'; +import { hubAPI } from '@ansible/hub-ui/common/api/formatPath'; +import { http, HttpResponse } from 'msw'; +import { setupServer } from 'msw/node'; +import type { ComponentProps } from 'react'; +import { useEffect } from 'react'; +import { SWRConfig } from 'swr'; +import { afterAll, afterEach, beforeAll, describe, expect, it, vi } from 'vitest'; +import platformLogo from '../assets/platform-logo.svg?url'; +import platformLogoWhite from '../assets/platform-logo-white.svg?url'; +import { PlatformAbout } from './PlatformAbout'; + +vi.mock('@patternfly/react-core', async (importOriginal) => { + const actual = await importOriginal(); + const PfAboutModal = actual.AboutModal; + return { + ...actual, + AboutModal: (props: ComponentProps) => ( + + ), + }; +}); + +function OpenPlatformAboutDialog() { + const [, setDialog] = usePageDialog(); + useEffect(() => { + setDialog(); + }, [setDialog]); + return null; +} + +function mountAbout(settings: IPageSettings) { + return render( + new Map(), dedupingInterval: 0 }}> + + + + + + + ); +} + +async function expectAboutDialogAbsent() { + await waitFor(() => expect(screen.queryByRole('dialog')).not.toBeInTheDocument()); +} + +async function setupLightAboutDialog() { + const user = userEvent.setup(); + mountAbout({ activeTheme: 'light' }); + const dialog = await screen.findByRole('dialog'); + return { user, dialog }; +} + +describe('PlatformAbout', () => { + const server = setupServer( + http.get(awxAPI`/ping/`, () => HttpResponse.json({ version: '4.5.0' })), + http.get(hubAPI`/`, () => HttpResponse.json({ galaxy_ng_version: '4.9.0' })), + http.get(edaAPI`/config/`, () => HttpResponse.json({ version: '1.2.0' })) + ); + + beforeAll(() => server.listen({ onUnhandledRequest: 'warn' })); + afterEach(() => server.resetHandlers()); + afterAll(() => server.close()); + + it('should display complete content with versions from APIs', async () => { + mountAbout({ activeTheme: 'light' }); + const dialog = await screen.findByRole('dialog'); + + expect(within(dialog).getByText(/Ansible Automation Platform/)).toBeInTheDocument(); + expect(within(dialog).getByText(/Copyright.*Red Hat/)).toBeInTheDocument(); + + await waitFor(() => { + expect(within(dialog).getByText('Automation Controller Version')).toBeInTheDocument(); + expect(within(dialog).getByText('4.5.0')).toBeInTheDocument(); + }); + await waitFor(() => { + expect(within(dialog).getByText('Event-Driven Ansible Version')).toBeInTheDocument(); + expect(within(dialog).getByText('1.2.0')).toBeInTheDocument(); + }); + await waitFor(() => { + expect(within(dialog).getByText('Automation Hub Version')).toBeInTheDocument(); + expect(within(dialog).getByText('4.9.0')).toBeInTheDocument(); + }); + }); + + it.each([ + { + label: 'light', + activeTheme: 'light' as const, + expectedSrc: platformLogo, + }, + { + label: 'dark', + activeTheme: 'dark' as const, + expectedSrc: platformLogoWhite, + }, + ])('should set brand image src for %# $label theme', async ({ activeTheme, expectedSrc }) => { + mountAbout({ activeTheme }); + const dialog = await screen.findByRole('dialog'); + expect(within(dialog).getByRole('img', { name: 'Brand Logo' })).toHaveAttribute( + 'src', + expectedSrc + ); + }); + + it('should close when the close button is activated', async () => { + const { user } = await setupLightAboutDialog(); + await user.click(screen.getByRole('button', { name: /close/i })); + await expectAboutDialogAbsent(); + }); + + it('should close when Escape is pressed', async () => { + const { user, dialog } = await setupLightAboutDialog(); + dialog.focus(); + await user.keyboard('{Escape}'); + await expectAboutDialogAbsent(); + }); +}); diff --git a/platform/main/PlatformAbout.tsx b/platform/main/PlatformAbout.tsx index f8b3b638fe..7d81b7106e 100644 --- a/platform/main/PlatformAbout.tsx +++ b/platform/main/PlatformAbout.tsx @@ -4,14 +4,15 @@ import { useGet } from '@ansible/common-ui/crud/useGet'; import { edaAPI } from '@ansible/eda-ui/common/eda-utils'; import { hubAPI } from '@ansible/hub-ui/common/api/formatPath'; import { AboutModal, Content } from '@patternfly/react-core'; -import { t } from 'i18next'; import React, { useContext } from 'react'; +import { useTranslation } from 'react-i18next'; import platformLogo from '../assets/platform-logo.svg?url'; import platformLogoWhite from '../assets/platform-logo-white.svg?url'; export const PlatformAbout: React.FunctionComponent<{ platformVersion?: string; }> = ({ platformVersion }) => { + const { t } = useTranslation(); const awxInfo = useGet<{ version: string }>(awxAPI`/ping/`); const hubInfo = useGet<{ galaxy_ng_version: string }>(hubAPI`/`); const edaInfo = useGet<{ version: string }>(edaAPI`/config/`); diff --git a/platform/main/PlatformMasthead.test.tsx b/platform/main/PlatformMasthead.test.tsx new file mode 100644 index 0000000000..5b070d7422 --- /dev/null +++ b/platform/main/PlatformMasthead.test.tsx @@ -0,0 +1,192 @@ +import { + PageDialogProvider, + PageNavSideBarProvider, + PageSettingsContext, + type IPageSettings, + type WindowSize, +} from '@ansible/ansible-ui-framework'; +import { render, screen, within } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import type { QuickStart } from '@patternfly/quickstarts'; +import { MemoryRouter } from 'react-router-dom'; +import { SWRConfig } from 'swr'; +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; +import { PlatformMasthead } from './PlatformMasthead'; +import { PlatformRoute } from './PlatformRoutes'; + +const { mockPageNavigate, mockUseBreakpoint } = vi.hoisted(() => ({ + mockPageNavigate: vi.fn(), + mockUseBreakpoint: vi.fn((_size: WindowSize) => true), +})); + +vi.mock('@ansible/ansible-ui-framework', async () => { + const actual = await vi.importActual( + '@ansible/ansible-ui-framework' + ); + return { + ...actual, + usePageNavigate: () => mockPageNavigate, + PageNotificationsIcon: () => , + useBreakpoint: (size: WindowSize) => mockUseBreakpoint(size), + }; +}); + +vi.mock('@ansible/awx-ui/main/AwxMasthead', () => ({ + useAwxNotifications: () => undefined, +})); + +vi.mock('@ansible/hub-ui/main/HubMasthead', () => ({ + useHubNotifications: () => undefined, +})); + +vi.mock('../notifications/useRssNotifications', () => ({ + useRssNotifications: () => undefined, +})); + +vi.mock('@ansible/awx-ui/common/useAwxActiveUser', () => ({ + useAwxActiveUser: () => ({ refreshActiveAwxUser: vi.fn() }), +})); + +vi.mock('@ansible/eda-ui/common/useEdaActiveUser', () => ({ + useEdaActiveUser: () => ({ refreshActiveEdaUser: vi.fn() }), +})); + +vi.mock('@ansible/hub-ui/common/useHubActiveUser', () => ({ + useHubActiveUser: () => ({ refreshActiveHubUser: vi.fn() }), +})); + +vi.mock('@ansible/common-ui/utils/useDocsVersion', () => ({ + useDocsVersion: () => ({ version: '2.5' }), +})); + +vi.mock('@ansible/common-ui/PageRefreshIcon', () => ({ + PageRefreshIcon: () => null, +})); + +vi.mock('@ansible/chatbot/ChatbotToolbarItem', () => ({ + ChatbotToolbarItem: () => null, +})); + +vi.mock('../overview/quickstarts/useQuickStarts', () => ({ + useQuickStarts: vi.fn(() => [{ metadata: { name: 'qs-1' } } as QuickStart]), +})); + +vi.mock('./PlatformActiveUserProvider', () => ({ + usePlatformActiveUser: () => ({ + activePlatformUser: { id: 1, username: 'admin' }, + refreshActivePlatformUser: vi.fn(), + }), +})); + +vi.mock('./GatewayUIAuth', () => ({ + useIsManagedCloudInstall: () => false, +})); + +function mountMasthead(settings?: IPageSettings) { + const pageSettings: IPageSettings = settings ?? { activeTheme: 'light', theme: 'light' }; + return render( + + new Map(), dedupingInterval: 0 }}> + + + + + + + + + + ); +} + +function getHelpMenuToggle(): HTMLElement { + const el = document.getElementById('help-menu-menu-toggle'); + if (!el) { + throw new Error('Expected #help-menu-menu-toggle to be in the document'); + } + return el; +} + +describe('PlatformMasthead help menu', () => { + beforeEach(() => { + mockPageNavigate.mockClear(); + mockUseBreakpoint.mockImplementation(() => true); + }); + + afterEach(() => { + vi.clearAllMocks(); + }); + + it('should display help toggle with correct initial state and toggle open/closed', async () => { + const user = userEvent.setup(); + mountMasthead(); + + const helpToggle = getHelpMenuToggle(); + expect(helpToggle).toHaveAttribute('aria-expanded', 'false'); + + await user.click(helpToggle); + expect(helpToggle).toHaveAttribute('aria-expanded', 'true'); + expect(screen.getByTestId('masthead-documentation')).toBeVisible(); + expect(screen.getByTestId('masthead-about')).toBeVisible(); + + await user.click(helpToggle); + expect(helpToggle).toHaveAttribute('aria-expanded', 'false'); + expect(screen.queryByTestId('masthead-documentation')).not.toBeInTheDocument(); + }); + + it('should display documentation link with correct href', async () => { + const user = userEvent.setup(); + mountMasthead(); + + await user.click(getHelpMenuToggle()); + const docItem = screen.getByTestId('masthead-documentation'); + expect(within(docItem).getByRole('menuitem', { name: 'Documentation' })).toHaveAttribute( + 'href', + 'https://access.redhat.com/documentation/en-us/red_hat_ansible_automation_platform' + ); + }); + + it('should call pageNavigate for Quick starts when the entry is shown', async () => { + const user = userEvent.setup(); + mountMasthead(); + + await user.click(getHelpMenuToggle()); + await user.click(screen.getByRole('menuitem', { name: 'Quick starts' })); + expect(mockPageNavigate).toHaveBeenCalledWith(PlatformRoute.QuickStarts); + }); + + it('should be keyboard navigable on the help menu toggle', async () => { + const user = userEvent.setup(); + mountMasthead(); + + const helpToggle = getHelpMenuToggle(); + helpToggle.focus(); + expect(helpToggle).toHaveFocus(); + + await user.keyboard('{Enter}'); + expect(helpToggle).toHaveAttribute('aria-expanded', 'true'); + expect(screen.getByTestId('masthead-documentation')).toBeVisible(); + + await user.keyboard('{Escape}'); + expect(helpToggle).toHaveAttribute('aria-expanded', 'false'); + + helpToggle.focus(); + await user.keyboard('{Enter}'); + expect(helpToggle).toHaveAttribute('aria-expanded', 'true'); + + await user.keyboard('{Escape}'); + expect(helpToggle).toHaveAttribute('aria-expanded', 'false'); + }); + + it('should keep help menu usable when only small breakpoints resolve', async () => { + const user = userEvent.setup(); + mockUseBreakpoint.mockImplementation((size: WindowSize) => size === 'sm'); + mountMasthead(); + + const helpToggle = getHelpMenuToggle(); + expect(helpToggle).toBeVisible(); + await user.click(helpToggle); + expect(screen.getByTestId('masthead-documentation')).toBeVisible(); + expect(screen.getByTestId('masthead-about')).toBeVisible(); + }); +}); diff --git a/platform/main/PlatformMasthead.tsx b/platform/main/PlatformMasthead.tsx index 4a6965c329..8317a6d994 100644 --- a/platform/main/PlatformMasthead.tsx +++ b/platform/main/PlatformMasthead.tsx @@ -107,7 +107,7 @@ export function PlatformMasthead() { {!managedCloudInstall && quickStarts.length > 0 ? ( pageNavigate(PlatformRoute.QuickStarts)} data-cy="masthead-quickstarts" data-testid="masthead-quickstarts" diff --git a/playwright/tests/integration/platform/help-menu.spec.ts b/playwright/tests/integration/platform/help-menu.spec.ts index 298a6b144a..3b4152702a 100644 --- a/playwright/tests/integration/platform/help-menu.spec.ts +++ b/playwright/tests/integration/platform/help-menu.spec.ts @@ -1,281 +1,71 @@ import { TOPOLOGY_AZURE, TOPOLOGY_SAAS } from '@ansible/playwright/commands/constants'; -import { isTopology, isSaaS } from '@ansible/playwright/commands/getTopologyType'; +import { isSaaS, isTopology } from '@ansible/playwright/commands/getTopologyType'; import { setupAfter, setupBefore } from '@ansible/playwright/commands/setup'; import { expect, test } from '@playwright/test'; -// Type definitions for API responses -interface AwxConfig { - version: string; - [key: string]: unknown; -} - -interface HubConfig { - galaxy_ng_version: string; - [key: string]: unknown; -} - -interface EdaConfig { - version: string; - [key: string]: unknown; -} +type ServiceVersionJson = { version: string }; +type HubRootJson = { galaxy_ng_version: string }; test.beforeEach(setupBefore({ path: '/' })); test.afterEach(setupAfter); test.describe('Platform Header Toolbar - Help Menu', () => { - test.describe('Help Menu Toggle and Display', () => { - test( - 'should display button with correct initial state and toggle open/closed', - { tag: ['@not_mock'] }, - async ({ page }) => { - // Initial state - button should be visible and closed - const helpMenuToggle = page.locator('#help-menu-menu-toggle'); - await expect(helpMenuToggle).toBeVisible(); - await expect(helpMenuToggle).toHaveAttribute('aria-expanded', 'false'); - // Open menu - await helpMenuToggle.click(); - await expect(helpMenuToggle).toHaveAttribute('aria-expanded', 'true'); - // Verify menu items are visible - await expect(page.locator('[data-testid="masthead-documentation"]')).toBeVisible(); - await expect(page.locator('[data-testid="masthead-about"]')).toBeVisible(); - // Close menu by clicking toggle again - await helpMenuToggle.click(); - await expect(helpMenuToggle).toHaveAttribute('aria-expanded', 'false'); - // Verify menu is closed - await expect(page.locator('[data-testid="masthead-documentation"]')).not.toBeVisible(); - } - ); - }); - - test.describe('Menu Items', () => { - test( - 'menu should display documentation link with correct attributes', - { tag: ['@not_mock'] }, - async ({ page }) => { - // Open help menu - await page.locator('#help-menu-menu-toggle').click(); - // Verify documentation item - const docItem = page.locator('[data-testid="masthead-documentation"]'); - await expect(docItem).toBeVisible(); - await expect(docItem).toContainText('Documentation'); - // Verify link attributes - const docLink = docItem.locator('a'); - await expect(docLink).toHaveAttribute( - 'href', - 'https://access.redhat.com/documentation/en-us/red_hat_ansible_automation_platform' - ); - } - ); - }); - - test.describe('Quick Starts', () => { - test( - 'should conditionally display based on topology type', - { tag: ['@not_mock'] }, - async ({ page }) => { - // Open help menu - await page.locator('#help-menu-menu-toggle').click(); - if (isTopology(TOPOLOGY_SAAS, TOPOLOGY_AZURE)) { - // Quick starts should NOT exist in SaaS/Azure deployments - await expect(page.locator('[data-testid="masthead-quickstarts"]')).not.toBeVisible(); - } else { - // Quick starts should exist in other deployments - const quickStartsItem = page.locator('[data-testid="masthead-quickstarts"]'); - await expect(quickStartsItem).toBeVisible(); - await expect(quickStartsItem).toContainText('Quick starts'); - } - } - ); - - test( - 'should navigate to quick starts page and close menu', - { tag: ['@not_mock'] }, - async ({ page }) => { - // Skip for SaaS/Azure - if (isTopology(TOPOLOGY_SAAS, TOPOLOGY_AZURE)) { - test.skip(); - return; - } - // Open help menu - const helpMenuToggle = page.locator('#help-menu-menu-toggle'); - await helpMenuToggle.click(); - // Click quick starts - await page.locator('[data-testid="masthead-quickstarts"]').click(); - // Verify navigation occurred - await expect(page).toHaveURL(/\/quickstarts/); - // Verify menu closed after navigation - await expect(helpMenuToggle).toHaveAttribute('aria-expanded', 'false'); - // Verify quick starts page loaded - await expect( - page.getByRole('heading', { name: 'Quick Starts', exact: true }) - ).toBeVisible(); - await expect( - page.getByText('Learn Ansible automation with hands-on quickstarts.') - ).toBeVisible(); - } - ); - }); - - test.describe('About Modal: Content Display', () => { - test( - 'should display complete content with versions from APIs', - { tag: ['@not_mock'] }, - async ({ page }) => { - // Set up API intercepts - const awxConfigPromise = page.waitForResponse( - (response) => - response.url().includes('/api/controller/v2/ping/') && - response.request().method() === 'GET' - ); - const hubConfigPromise = page.waitForResponse( - (response) => - response.url().includes('/api/galaxy/') && response.request().method() === 'GET' - ); - // Open help menu and click About - await page.locator('#help-menu-menu-toggle').click(); - await page.locator('[data-testid="masthead-about"]').click(); - // Wait for API responses - const awxResponse = await awxConfigPromise; - const hubResponse = await hubConfigPromise; - const awxConfig = (await awxResponse.json()) as AwxConfig; - const hubConfig = (await hubResponse.json()) as HubConfig; - // Verify modal is visible - const modal = page.getByRole('dialog'); - await expect(modal).toBeVisible(); - // Verify modal title/branding - await expect(modal.getByText(/Ansible Automation Platform/)).toBeVisible(); - // Verify trademark/copyright - await expect(modal.getByText(/Copyright.*Red Hat/)).toBeVisible(); - // Verify Automation Controller Version - await expect(modal.getByText('Automation Controller Version')).toBeVisible(); - if (awxConfig.version) { - await expect(modal.getByText(awxConfig.version, { exact: true })).toBeVisible(); - } - // Verify Automation Hub Version - await expect(modal.getByText('Automation Hub Version')).toBeVisible(); - if (hubConfig.galaxy_ng_version) { - await expect(modal.getByText(hubConfig.galaxy_ng_version, { exact: true })).toBeVisible(); - } - // For non-SaaS deployments, verify EDA version - if (!isSaaS()) { - const edaConfigPromise = page.waitForResponse( + test( + 'should conditionally display based on topology type', + { tag: ['@not_mock'] }, + async ({ page }) => { + const awxConfigPromise = page.waitForResponse( + (response) => + response.url().includes('/api/controller/v2/ping/') && + response.request().method() === 'GET' + ); + const hubConfigPromise = page.waitForResponse( + (response) => + response.url().includes('/api/galaxy/') && response.request().method() === 'GET' + ); + const edaConfigPromise = isSaaS() + ? null + : page.waitForResponse( (response) => response.url().includes('/api/eda/v1/config/') && response.request().method() === 'GET' ); - const edaResponse = await edaConfigPromise; - const edaConfig = (await edaResponse.json()) as EdaConfig; - await expect(modal.getByText('Event-Driven Ansible Version')).toBeVisible(); - if (edaConfig.version) { - await expect(modal.getByText(edaConfig.version, { exact: true })).toBeVisible(); - } - } - } - ); - }); - - test.describe('About Modal: Brand Logo', () => { - test( - 'should display brand logo that loads successfully', - { tag: ['@not_mock'] }, - async ({ page }) => { - await page.locator('#help-menu-menu-toggle').click(); - await page.locator('[data-testid="masthead-about"]').click(); - - const modal = page.getByRole('dialog'); - const brandLogo = modal.locator('img[alt="Brand Logo"]'); - - await expect(brandLogo).toBeVisible(); - await expect(brandLogo).toHaveAttribute('alt', 'Brand Logo'); - const naturalWidth = await brandLogo.evaluate((img: HTMLImageElement) => img.naturalWidth); - expect(naturalWidth).toBeGreaterThan(0); - } - ); - - test('should load white logo for dark theme', { tag: ['@not_mock'] }, async ({ page }) => { - const themeButton = page.locator('[data-cy="theme-icon"]'); - await expect(themeButton).toBeVisible(); - await themeButton.click(); await page.locator('#help-menu-menu-toggle').click(); - await page.locator('[data-testid="masthead-about"]').click(); - const modal = page.getByRole('dialog'); - const brandLogo = modal.locator('img[alt="Brand Logo"]'); - - await expect(brandLogo).toBeVisible(); - const naturalWidth = await brandLogo.evaluate((img: HTMLImageElement) => img.naturalWidth); - expect(naturalWidth).toBeGreaterThan(0); - }); - - test('should load standard logo for light theme', { tag: ['@not_mock'] }, async ({ page }) => { - await page.locator('#help-menu-menu-toggle').click(); - await page.locator('[data-testid="masthead-about"]').click(); - - const modal = page.getByRole('dialog'); - const brandLogo = modal.locator('img[alt="Brand Logo"]'); - - await expect(brandLogo).toBeVisible(); - const naturalWidth = await brandLogo.evaluate((img: HTMLImageElement) => img.naturalWidth); - expect(naturalWidth).toBeGreaterThan(0); - }); - }); - - test.describe('About Modal: User Interactions', () => { - test('should close using X button', { tag: ['@not_mock'] }, async ({ page }) => { - // Open about modal - await page.locator('#help-menu-menu-toggle').click(); - await page.locator('[data-testid="masthead-about"]').click(); - const modal = page.getByRole('dialog'); - await expect(modal).toBeVisible(); - // Click close button - await modal.locator('button[aria-label*="Close"]').first().click(); - await expect(modal).not.toBeVisible(); - }); + if (isTopology(TOPOLOGY_SAAS, TOPOLOGY_AZURE)) { + await expect(page.locator('[data-testid="masthead-quickstarts"]')).not.toBeVisible(); + } else { + const quickStartsItem = page.locator('[data-testid="masthead-quickstarts"]'); + await expect(quickStartsItem).toBeVisible(); + await expect(quickStartsItem).toContainText('Quick starts'); + } - test('should close using ESC key', { tag: ['@not_mock'] }, async ({ page }) => { - // Open about modal - await page.locator('#help-menu-menu-toggle').click(); await page.locator('[data-testid="masthead-about"]').click(); + const awxResponse = await awxConfigPromise; + const hubResponse = await hubConfigPromise; + const awxConfig = (await awxResponse.json()) as ServiceVersionJson; + const hubConfig = (await hubResponse.json()) as HubRootJson; const modal = page.getByRole('dialog'); await expect(modal).toBeVisible(); - // Press ESC - await page.keyboard.press('Escape'); - await expect(modal).not.toBeVisible(); - }); - }); - - test.describe('Accessibility', () => { - test('should be keyboard navigable', { tag: ['@not_mock'] }, async ({ page }) => { - // Focus help menu button - const helpMenuToggle = page.locator('#help-menu-menu-toggle'); - await helpMenuToggle.focus(); - await expect(helpMenuToggle).toBeFocused(); - // Open with Enter key - await page.keyboard.press('Enter'); - await expect(helpMenuToggle).toHaveAttribute('aria-expanded', 'true'); - await expect(page.locator('[data-testid="masthead-documentation"]')).toBeVisible(); - // Close with Escape key - await page.keyboard.press('Escape'); - await expect(helpMenuToggle).toHaveAttribute('aria-expanded', 'false'); - // Open with Space key - await helpMenuToggle.focus(); - await page.keyboard.press('Space'); - await expect(helpMenuToggle).toHaveAttribute('aria-expanded', 'true'); - // Close again - await page.keyboard.press('Escape'); - }); - }); - - test.describe('Responsive Design', () => { - test('should work on tablet viewport', { tag: ['@not_mock'] }, async ({ page }) => { - // Set tablet viewport - await page.setViewportSize({ width: 768, height: 1024 }); - const helpMenuToggle = page.locator('#help-menu-menu-toggle'); - await expect(helpMenuToggle).toBeVisible(); - await helpMenuToggle.click(); - await expect(page.locator('[data-testid="masthead-documentation"]')).toBeVisible(); - await expect(page.locator('[data-testid="masthead-about"]')).toBeVisible(); - }); - }); + await expect(modal.getByText(/Ansible Automation Platform/)).toBeVisible(); + await expect(modal.getByText(/Copyright.*Red Hat/)).toBeVisible(); + await expect(modal.getByText('Automation Controller Version')).toBeVisible(); + if (awxConfig.version) { + await expect(modal.getByText(awxConfig.version, { exact: true })).toBeVisible(); + } + await expect(modal.getByText('Automation Hub Version')).toBeVisible(); + if (hubConfig.galaxy_ng_version) { + await expect(modal.getByText(hubConfig.galaxy_ng_version, { exact: true })).toBeVisible(); + } + if (edaConfigPromise) { + const edaResponse = await edaConfigPromise; + const edaConfig = (await edaResponse.json()) as ServiceVersionJson; + await expect(modal.getByText('Event-Driven Ansible Version')).toBeVisible(); + if (edaConfig.version) { + await expect(modal.getByText(edaConfig.version, { exact: true })).toBeVisible(); + } + } + } + ); });