From a137a55ff35c4f0b832154c6d7ecb5b4f7bfce12 Mon Sep 17 00:00:00 2001 From: Gustavo Lira Date: Wed, 3 Jul 2024 20:27:45 -0300 Subject: [PATCH] RHIDP-744 [Test Automation] Automate RHDH theme customization - E2E Refactor custom theme E2E test and update uihelper functions The custom theme end-to-end test was refactored to be more focused and reliable. The 'UIhelper' was enriched with new functions that improve reusability in tests. Also, configuration for application theming and authentication methods were updated. Signed-off-by: Gustavo Lira --- .../config_map/configmap-app-config-rhdh.yaml | 10 ++-- e2e-tests/playwright/e2e/custom-theme.spec.ts | 50 ------------------ .../plugins/custom-theme/custom-theme.spec.ts | 52 +++++++++++++++++++ .../support/pageObjects/global-obj.ts | 4 ++ e2e-tests/playwright/utils/UIhelper.ts | 36 ++++++++++++- 5 files changed, 98 insertions(+), 54 deletions(-) delete mode 100644 e2e-tests/playwright/e2e/custom-theme.spec.ts create mode 100644 e2e-tests/playwright/e2e/plugins/custom-theme/custom-theme.spec.ts diff --git a/.ibm/pipelines/resources/config_map/configmap-app-config-rhdh.yaml b/.ibm/pipelines/resources/config_map/configmap-app-config-rhdh.yaml index 72cd88b1f6..a71a435713 100644 --- a/.ibm/pipelines/resources/config_map/configmap-app-config-rhdh.yaml +++ b/.ibm/pipelines/resources/config_map/configmap-app-config-rhdh.yaml @@ -16,6 +16,11 @@ data: headerColor1: "rgb(248, 248, 248)" headerColor2: "rgb(248, 248, 248)" navigationIndicatorColor: "rgb(255,95,21)" + dark: + primaryColor: '#ab75cf' + headerColor1: 'rgb(0, 0, 208)' + headerColor2: 'rgb(255, 246, 140)' + navigationIndicatorColor: 'rgb(244, 238, 169)' backend: auth: keys: @@ -44,6 +49,8 @@ data: # see https://backstage.io/docs/auth/ to learn about auth providers environment: development providers: + guest: + dangerouslyAllowOutsideDevelopment: true # Plugin: GitHub github: development: @@ -53,8 +60,6 @@ data: development: clientId: ${GOOGLE_CLIENT_ID} clientSecret: ${GOOGLE_CLIENT_SECRET} - guest: - dangerouslyAllowOutsideDevelopment: true proxy: skipInvalidProxies: true @@ -99,7 +104,6 @@ data: rules: - allow: [User, Group] - dynatrace: baseUrl: temp argocd: diff --git a/e2e-tests/playwright/e2e/custom-theme.spec.ts b/e2e-tests/playwright/e2e/custom-theme.spec.ts deleted file mode 100644 index 80afd7674d..0000000000 --- a/e2e-tests/playwright/e2e/custom-theme.spec.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { test, Page, expect } from '@playwright/test'; -import { UIhelper } from '../utils/UIhelper'; -import { Common, setupBrowser } from '../utils/Common'; - -let page: Page; - -test.describe('CustomTheme should be applied', () => { - let common: Common; - let uiHelper: UIhelper; - - test.beforeAll(async ({ browser }, testInfo) => { - page = (await setupBrowser(browser, testInfo)).page; - common = new Common(page); - uiHelper = new UIhelper(page); - - await common.loginAsGuest(); - }); - - /* eslint-disable-next-line no-empty-pattern */ - test('Verify that theme colors are applied and make screenshots', async ({} /* NOSONAR */, testInfo) => { - await uiHelper.openSidebar('Settings'); - - const header = await page.locator('header').first(); - await expect(header).toHaveCSS( - 'background-image', - 'none, linear-gradient(90deg, rgb(248, 248, 248), rgb(248, 248, 248))', - ); - - await page.screenshot({ - path: 'screenshots/cusotm-theme-inspection.png', - fullPage: true, - }); - - await testInfo.attach('cusotm-theme-inspection', { - path: 'screenshots/cusotm-theme-inspection.png', - }); - - await page.locator('[name=pin]').click(); - - await page.screenshot({ - path: 'screenshots/cusotm-theme-inspection-collapsed.png', - fullPage: true, - }); - await testInfo.attach('cusotm-theme-inspection-collapsed', { - path: 'screenshots/cusotm-theme-inspection-collapsed.png', - }); - - await common.signOut(); - }); -}); diff --git a/e2e-tests/playwright/e2e/plugins/custom-theme/custom-theme.spec.ts b/e2e-tests/playwright/e2e/plugins/custom-theme/custom-theme.spec.ts new file mode 100644 index 0000000000..665c361735 --- /dev/null +++ b/e2e-tests/playwright/e2e/plugins/custom-theme/custom-theme.spec.ts @@ -0,0 +1,52 @@ +import { test, Page, TestInfo } from '@playwright/test'; +import { Common, setupBrowser } from '../../../utils/Common'; +import { ThemeVerifier } from './theme-verifier'; + +let page: Page; + +test.describe('CustomTheme should be applied', () => { + let common: Common; + let themeVerifier: ThemeVerifier; + + test.beforeAll(async ({ browser }, testInfo) => { + page = (await setupBrowser(browser, testInfo)).page; + common = new Common(page); + themeVerifier = new ThemeVerifier(page); + + await common.loginAsGuest(); + }); + + // eslint-disable-next-line no-empty-pattern + test('Verify that theme light colors are applied and make screenshots', async ({}, testInfo: TestInfo) => { + await themeVerifier + .setTheme('Light') + .verifyHeaderGradient( + 'none, linear-gradient(90deg, rgb(248, 248, 248), rgb(248, 248, 248))', + ) + .verifyBorderLeftColor('rgb(255, 95, 21)') + .takeScreenshotAndAttach( + 'screenshots/custom-theme-light-inspection.png', + testInfo, + 'custom-theme-light-inspection', + ) + .verifyPrimaryColors('rgb(255, 95, 21)') + .execute(); + }); + + // eslint-disable-next-line no-empty-pattern + test('Verify that theme dark colors are applied and make screenshots', async ({}, testInfo: TestInfo) => { + await themeVerifier + .setTheme('Dark') + .verifyHeaderGradient( + 'none, linear-gradient(90deg, rgb(0, 0, 208), rgb(255, 246, 140))', + ) + .verifyBorderLeftColor('rgb(244, 238, 169)') + .takeScreenshotAndAttach( + 'screenshots/custom-theme-dark-inspection.png', + testInfo, + 'custom-theme-dark-inspection', + ) + .verifyPrimaryColors('#ab75cf') + .execute(); + }); +}); diff --git a/e2e-tests/playwright/support/pageObjects/global-obj.ts b/e2e-tests/playwright/support/pageObjects/global-obj.ts index 0e26b082e2..7cf4d146be 100644 --- a/e2e-tests/playwright/support/pageObjects/global-obj.ts +++ b/e2e-tests/playwright/support/pageObjects/global-obj.ts @@ -5,10 +5,14 @@ export const waitsObjs = { export const UIhelperPO = { MuiButtonLabel: 'span[class^="MuiButton-label"]', + MuiToggleButtonLabel: 'span[class^="MuiToggleButton-label"]', MuiBoxLabel: 'div[class*="MuiBox-root"] label', MuiTableHead: 'th[class*="MuiTableCell-root"]', MuiTableCell: 'td[class*="MuiTableCell-root"]', MuiTableRow: 'tr[class*="MuiTableRow-root"]', + MuiTypographyColorPrimary: '.MuiTypography-colorPrimary', + MuiSwitchColorPrimary: '.MuiSwitch-colorPrimary', + MuiButtonTextPrimary: '.MuiButton-textPrimary', MuiCard: cardHeading => `//div[contains(@class,'MuiCardHeader-root') and descendant::*[text()='${cardHeading}']]/..`, MuiTable: 'table.MuiTable-root', diff --git a/e2e-tests/playwright/utils/UIhelper.ts b/e2e-tests/playwright/utils/UIhelper.ts index 11699fe7bb..d787fd2ef9 100644 --- a/e2e-tests/playwright/utils/UIhelper.ts +++ b/e2e-tests/playwright/utils/UIhelper.ts @@ -3,7 +3,6 @@ import { UIhelperPO } from '../support/pageObjects/global-obj'; export class UIhelper { private page: Page; - private selectors: { [key: string]: string }; constructor(page: Page) { this.page = page; @@ -46,6 +45,15 @@ export class UIhelper { return button; } + async clickBtnByTitleIfNotPressed(title: string) { + const button = this.page.locator(`button[title="${title}"]`); + const isPressed = await button.getAttribute('aria-pressed'); + + if (isPressed === 'false') { + await button.click(); + } + } + async verifyDivHasText(divText: string) { await expect( this.page.locator(`div`).filter({ hasText: divText }), @@ -247,4 +255,30 @@ export class UIhelper { const rowCount = await this.page.locator(rowSelector).count(); expect(rowCount).toBeGreaterThan(0); } + + // Function to convert hexadecimal to RGB or return RGB if it's already in RGB + toRgb(color: string): string { + if (color.startsWith('rgb')) { + return color; + } + + const bigint = parseInt(color.slice(1), 16); + const r = (bigint >> 16) & 255; + const g = (bigint >> 8) & 255; + const b = bigint & 255; + return `rgb(${r}, ${g}, ${b})`; + } + + async checkCssColor(page: Page, selector: string, expectedColor: string) { + const elements = await page.locator(selector); + const count = await elements.count(); + const expectedRgbColor = this.toRgb(expectedColor); + + for (let i = 0; i < count; i++) { + const color = await elements + .nth(i) + .evaluate(el => window.getComputedStyle(el).color); + expect(color).toBe(expectedRgbColor); + } + } }