diff --git a/package.json b/package.json index c8e20f4..280f418 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "lint": "eslint --ext .js,.ts,.vue ./", "dev:electron": "quasar dev -m electron", "build": "quasar build -m electron --publish never", - "test:component": "node \"node_modules/@playwright/test/cli.js\" test src/components/", + "test:component": "node \"node_modules/@playwright/test/cli.js\" test src/components", "test:e2e": "node \"node_modules/@playwright/test/cli.js\" test test/playwright-e2e/" }, "dependencies": { diff --git a/src/components/AppControlMenus/AppControlSingleMenu/AppControlSingleMenu.playwright.test.ts b/src/components/AppControlMenus/AppControlSingleMenu/AppControlSingleMenu.playwright.test.ts index 8c2522e..759594c 100644 --- a/src/components/AppControlMenus/AppControlSingleMenu/AppControlSingleMenu.playwright.test.ts +++ b/src/components/AppControlMenus/AppControlSingleMenu/AppControlSingleMenu.playwright.test.ts @@ -2,6 +2,7 @@ import { _electron as electron } from 'playwright' import { test, expect } from '@playwright/test' import { extraEnvVariablesAPI } from 'app/src-electron/customContentBridgeAPIs/extraEnvVariablesAPI' import { testData } from '../_testData/test.fixed.component' +import { rgbToHex } from 'src/scripts/_utilities/colorFormatConvertors' /** * Extra env settings to trigger component testing via Playwright @@ -90,9 +91,9 @@ test('Check if the "Menu title" element is properly loaded and has proper conten }) /** - * Check if the menu opens properly on click and all parts are loaded properly + * Check if the main menu has a wrapper, click and check if all menu elements loaded properly */ -test('Check if the menu has a wrapper, click if all menu elements loaded properly', async () => { +test('Check if the main menu has a wrapper, click and check if all menu elements loaded properly', async () => { const electronApp = await electron.launch({ env: extraEnvSettings, args: [electronMainFilePath] @@ -119,12 +120,10 @@ test('Check if the menu has a wrapper, click if all menu elements loaded properl } }) -// TODO add checking text color class! - /** - * Check if the first menu item has proper text and icon + * Check if the first main menu item has proper text and icon */ -test('Check if the first menu item has proper text and icon', async () => { +test('Check if the first main menu item has proper text and icon', async () => { const electronApp = await electron.launch({ env: extraEnvSettings, args: [electronMainFilePath] @@ -171,3 +170,242 @@ test('Check if the first menu item has proper text and icon', async () => { test.fail() } }) + +/** + * Check if text color class applied properly to any main menu item: Secondary + */ +test('Check if text color class applied properly to any main menu item: Secondary', async () => { + const testColorString = 'secondary' + const testColorHexString = '#f75746' + + const electronApp = await electron.launch({ + env: extraEnvSettings, + args: [electronMainFilePath] + }) + + const appWindow = await electronApp.firstWindow() + await appWindow.waitForTimeout(faFrontendRenderTimer) + + const menuWrapper = await appWindow.$(`[data-test="${selectorList.menuWrapper}"]`) + + // Check if wrapper exists for clicking and if so, click it + if (menuWrapper !== null) { + await menuWrapper.click() + + const colorMenuItem = await appWindow.$(`.text-${testColorString}[data-test="${selectorList.menuItem}"]`) + + // Check if the item wrapper exists + if (colorMenuItem !== null) { + const colorMenuString = await colorMenuItem.evaluate(el => getComputedStyle(el).getPropertyValue('color')) + const colorHexString = rgbToHex(colorMenuString) + + // Compare color of the string with secondary color + await expect(colorHexString).toBe(testColorHexString) + await electronApp.close() + } else { + // Item wrapper doesn't exist + test.fail() + } + } else { + // Wrapper for opening the menu doesn't exist + test.fail() + } +}) + +/** + * Check if the sub-menu opens properly on click of the main menu item and all parts are loaded properly + */ +test('Check if the sub-menu opens properly on click of the main menu item and all parts are loaded properly', async () => { + const electronApp = await electron.launch({ + env: extraEnvSettings, + args: [electronMainFilePath] + }) + + const appWindow = await electronApp.firstWindow() + await appWindow.waitForTimeout(faFrontendRenderTimer) + + const menuWrapper = await appWindow.$(`[data-test="${selectorList.menuWrapper}"]`) + + // Check if main menu wrapper exists for clicking and if so, click it + if (menuWrapper !== null) { + await menuWrapper.click() + await appWindow.waitForTimeout(600) + + const menuItems = await appWindow.$$(`[data-test="${selectorList.menuItem}"]`) + const dataElement = testData.data.filter(item => item.mode === 'item').find(el => el.submenu !== undefined) + const dataIndex = testData.data.filter(item => item.mode === 'item').findIndex(el => el.submenu !== undefined) + + const submenuTrigger = menuItems[dataIndex] + + // Check if the submenu trigger exists and click it if it does + if (submenuTrigger !== null) { + await submenuTrigger.click() + await appWindow.waitForTimeout(600) + } else { + // Submenu trigger doesn't exist + test.fail() + } + + const subMenuWrapper = await appWindow.$(`[data-test="${selectorList.menuItemSubMenu}"]`) + + // Check if submenu wrapper doesn't exist + if (subMenuWrapper === null) { + test.fail() + } + + const subMenuItems = await appWindow.$$(`[data-test="${selectorList.menuItemSubMenuItem}"]`) + const dataSubmenuItems = (dataElement?.submenu !== undefined) ? dataElement.submenu.filter(item => item.mode === 'item') : false + + const subMenuItemsCount = subMenuItems.length + const dataSubmenuItemsCount = (dataSubmenuItems) ? dataSubmenuItems.length : false + + await expect(subMenuItemsCount === dataSubmenuItemsCount).toBe(true) + await electronApp.close() + } else { + // Wrapper for opening the main menu doesn't exist + test.fail() + } +}) + +/** + * Check if the first sub-menu item has proper text and icon + */ +test('Check if the first sub-menu item has proper text and icon', async () => { + const electronApp = await electron.launch({ + env: extraEnvSettings, + args: [electronMainFilePath] + }) + + const appWindow = await electronApp.firstWindow() + await appWindow.waitForTimeout(faFrontendRenderTimer) + + const menuWrapper = await appWindow.$(`[data-test="${selectorList.menuWrapper}"]`) + + // Check if main menu wrapper exists for clicking and if so, click it + if (menuWrapper !== null) { + await menuWrapper.click() + await appWindow.waitForTimeout(600) + + const menuItems = await appWindow.$$(`[data-test="${selectorList.menuItem}"]`) + const dataElement = testData.data.filter(item => item.mode === 'item').find(el => el.submenu !== undefined) + const dataIndex = testData.data.filter(item => item.mode === 'item').findIndex(el => el.submenu !== undefined) + + const submenuTrigger = menuItems[dataIndex] + + // Check if the submenu trigger exists and click it if it does + if (submenuTrigger !== null) { + await submenuTrigger.click() + await appWindow.waitForTimeout(600) + } else { + // Submenu trigger doesn't exist + test.fail() + } + + const subMenuWrapper = await appWindow.$(`[data-test="${selectorList.menuItemSubMenu}"]`) + + // Check if submenu wrapper doesn't exist + if (subMenuWrapper === null) { + test.fail() + } + + const firstSubMenuItem = await appWindow.$(`[data-test="${selectorList.menuItemSubMenuItem}"]`) + const firstDataSubmenuItem = (dataElement?.submenu !== undefined) ? dataElement.submenu.filter(item => item.mode === 'item')[0] : false + + // Check if the sub-menu item wrapper exists and if the first data-item isn't false + if (firstSubMenuItem !== null && firstDataSubmenuItem) { + const firstSubmenuItemTextElement = await firstSubMenuItem.$(`[data-test="${selectorList.menuItemSubMenuItemText}"]`) + const firstSubmenuItemIconElement = await firstSubMenuItem.$(`[data-test="${selectorList.menuItemSubMenuItemIcon}"]`) + + // Check if the icon and text wrappers exist + if (firstSubmenuItemTextElement !== null && firstSubmenuItemIconElement !== null) { + const firstSubmenuItemText = await firstSubmenuItemTextElement.textContent() + const firstDataItemText = firstDataSubmenuItem.text + + const firstSubmenuItemIconClassObject = await firstSubmenuItemIconElement.evaluate(el => el.classList) + const firstSubmenuItemIconClassList = Object.values(firstSubmenuItemIconClassObject).concat() + const firstDataItemIcon = firstDataSubmenuItem.icon as string + + await expect(firstSubmenuItemText === firstDataItemText && firstSubmenuItemIconClassList.includes(firstDataItemIcon)).toBe(true) + await electronApp.close() + } else { + // Item text or icon wrappers don't exist + test.fail() + } + } else { + // Item wrapper doesn't exist + test.fail() + } + + await electronApp.close() + } else { + // Wrapper for opening the main menu doesn't exist + test.fail() + } +}) + +// TODO add checking for submenu text colors + +/** + * Check if text color class applied properly to any sub-main menu item: Secondary + */ +test('Check if text color class applied properly to any sub-main menu item: Secondary', async () => { + const testColorString = 'secondary' + const testColorHexString = '#f75746' + + const electronApp = await electron.launch({ + env: extraEnvSettings, + args: [electronMainFilePath] + }) + + const appWindow = await electronApp.firstWindow() + await appWindow.waitForTimeout(faFrontendRenderTimer) + + const menuWrapper = await appWindow.$(`[data-test="${selectorList.menuWrapper}"]`) + + // Check if main menu wrapper exists for clicking and if so, click it + if (menuWrapper !== null) { + await menuWrapper.click() + await appWindow.waitForTimeout(600) + + const menuItems = await appWindow.$$(`[data-test="${selectorList.menuItem}"]`) + const dataIndex = testData.data.filter(item => item.mode === 'item').findIndex(el => el.submenu !== undefined) + + const submenuTrigger = menuItems[dataIndex] + + // Check if the submenu trigger exists and click it if it does + if (submenuTrigger !== null) { + await submenuTrigger.click() + await appWindow.waitForTimeout(600) + } else { + // Submenu trigger doesn't exist + test.fail() + } + + const subMenuWrapper = await appWindow.$(`[data-test="${selectorList.menuItemSubMenu}"]`) + + // Check if submenu wrapper doesn't exist + if (subMenuWrapper === null) { + test.fail() + } + + const colorSubMenuItem = await appWindow.$(`.text-${testColorString}[data-test="${selectorList.menuItemSubMenuItem}"]`) + + // Check if the colored sub-menu item wrapper exists + if (colorSubMenuItem !== null) { + const colorMenuString = await colorSubMenuItem.evaluate(el => getComputedStyle(el).getPropertyValue('color')) + const colorHexString = rgbToHex(colorMenuString) + + // Compare color of the string with secondary color + await expect(colorHexString).toBe(testColorHexString) + await electronApp.close() + } else { + // Item wrapper doesn't exist + test.fail() + } + + await electronApp.close() + } else { + // Wrapper for opening the main menu doesn't exist + test.fail() + } +}) diff --git a/src/components/GlobalWindowButtons/GlobalWindowButtons.playwright.test.ts b/src/components/GlobalWindowButtons/GlobalWindowButtons.playwright.test.ts index fde0912..1edd570 100644 --- a/src/components/GlobalWindowButtons/GlobalWindowButtons.playwright.test.ts +++ b/src/components/GlobalWindowButtons/GlobalWindowButtons.playwright.test.ts @@ -115,14 +115,14 @@ test('Click resize button - "maximize"', async () => { // Click twice await resizeButton.click() - await appWindow.waitForTimeout(500) + await appWindow.waitForTimeout(1500) await resizeButton.click() } else { await resizeButton.click() } - await appWindow.waitForTimeout(500) + await appWindow.waitForTimeout(1500) isMaximized = await appWindow.evaluate(() => window.faWindowControlAPI.checkWindowMaximized()) await expect(isMaximized).toBe(true) diff --git a/src/scripts/_utilities/colorFormatConvertors.ts b/src/scripts/_utilities/colorFormatConvertors.ts new file mode 100644 index 0000000..373252f --- /dev/null +++ b/src/scripts/_utilities/colorFormatConvertors.ts @@ -0,0 +1,20 @@ +export function rgbToHex (color: string) { + const colorStringRegexMatch = color.match(/\d+/g) + if (colorStringRegexMatch !== null) { + const colorString = colorStringRegexMatch.map(function (x) { + x = parseInt(x).toString(16) + return (x.length === 1) ? '0' + x : x + }).join('') + return '#' + colorString + } + return false +} + +export function hexToRgb (hex: string) { + const bigint = parseInt(hex, 16) + const r = (bigint >> 16) & 255 + const g = (bigint >> 8) & 255 + const b = bigint & 255 + + return r + ',' + g + ',' + b +}