diff --git a/codeceptConfigHelper.js b/codeceptConfigHelper.js index 7a166f5fc..01d0be504 100644 --- a/codeceptConfigHelper.js +++ b/codeceptConfigHelper.js @@ -48,7 +48,7 @@ module.exports = { agentsPage: './tests/configuration/pages/agentsPage.js', pmmServerAdminSettingsPage: './tests/configuration/pages/pmmServerAdminSettingsPage.js', pmmSettingsPage: './tests/configuration/pages/pmmSettingsPage.js', - portalAPI: './tests/pages/api/portalAPI.js', + portalAPI: './tests/pages/api/portalApi.js', profileAPI: './tests/configuration/api/profileApi.js', qanDetails: './tests/QAN/pages/qanDetailsFragment.js', qanFilters: './tests/QAN/pages/qanFiltersFragment.js', diff --git a/playwright-tests/api/api.ts b/playwright-tests/api/api.ts index 2f3230142..414c3e982 100644 --- a/playwright-tests/api/api.ts +++ b/playwright-tests/api/api.ts @@ -1,11 +1,11 @@ -import { server } from '@api/server'; -import { settings } from '@tests/tests/configuration/api/settings'; -import { oktaApi } from '@api/oktaApi'; -import { portalAPI } from '@api/portalApi'; -import { serviceNowAPI } from '@api/serviceNowApi'; -import { inventory } from '@api/inventory'; -import { management } from '@api/management'; -import {apiHelper} from "@api/helpers/apiHelper"; +import { server } from '@api/server.api'; +import { settingsApi } from '@tests/configuration/api/settings.api'; +import { oktaApi } from '@api/okta.api'; +import { portalApi } from '@api/portal.api'; +import { serviceNowApi } from '@api/service-now.api'; +import { inventoryApi } from '@api/inventory.api'; +import { managementApi } from '@api/management.api'; +import { apiHelper } from '@api/helpers/api-helper'; /** * User facing api collection. Accessible on Frontend via /swagger path. @@ -22,12 +22,12 @@ export const api = { }, }, pmm: { - inventoryV1: inventory, - settingsV1: settings, + inventoryV1: inventoryApi, + settingsV1: settingsApi, serverV1: server, - managementV1: management, + managementV1: managementApi, }, okta: oktaApi, - portal: portalAPI, - serviceNow: serviceNowAPI, + portal: portalApi, + serviceNow: serviceNowApi, }; diff --git a/playwright-tests/api/helpers/apiHelper.ts b/playwright-tests/api/helpers/api-helper.ts similarity index 94% rename from playwright-tests/api/helpers/apiHelper.ts rename to playwright-tests/api/helpers/api-helper.ts index 44b27010f..4065ac8c9 100644 --- a/playwright-tests/api/helpers/apiHelper.ts +++ b/playwright-tests/api/helpers/api-helper.ts @@ -1,15 +1,11 @@ import { APIRequestContext, Page, expect, request, } from '@playwright/test'; -import config from '@tests/playwright.config'; -import grafanaHelper from '@helpers/grafanaHelper'; +import config from '@root/playwright.config'; +import grafanaHelper from '@helpers/grafana-helper'; import { APIResponse } from 'playwright-core'; import { ReadStream } from 'fs'; -export interface Settings { - pmm_public_address: string; -} - const getConfiguredRestApi = async (): Promise => { return request.newContext({ baseURL: config.use?.baseURL, @@ -20,7 +16,7 @@ const getConfiguredRestApi = async (): Promise => { }); }; -export const apiHelper = { +const apiHelper = { // TODO: move it from the helper to proper file API? It's not actually API call. confirmTour: async (page: Page) => { await page.route('**/v1/user', (route) => { @@ -91,3 +87,4 @@ export const apiHelper = { return response; }, }; +export default apiHelper; diff --git a/playwright-tests/api/helpers/portalApiHelper.ts b/playwright-tests/api/helpers/portal-api-helper.ts similarity index 79% rename from playwright-tests/api/helpers/portalApiHelper.ts rename to playwright-tests/api/helpers/portal-api-helper.ts index 860744f14..c9db1ed30 100644 --- a/playwright-tests/api/helpers/portalApiHelper.ts +++ b/playwright-tests/api/helpers/portal-api-helper.ts @@ -1,5 +1,5 @@ import { APIRequestContext, APIResponse, expect, request } from '@playwright/test'; -import { Constants } from '@helpers/Constants'; +import constants from '@helpers/constants'; const checkAndReturnResponse = async (r: APIResponse) => { await expect(r, `Expected to be OK: ${r.status()} ${r.statusText()}`).toBeOK(); @@ -25,7 +25,7 @@ interface ContextOptions { const getRequestContext = async ( { accessToken, timeout }: { accessToken?: string; timeout?: number; }, ): Promise => { - const options: ContextOptions = { baseURL: Constants.portal.url, timeout }; + const options: ContextOptions = { baseURL: constants.portal.url, timeout }; if (accessToken) { options.extraHTTPHeaders = { Authorization: `Bearer ${accessToken}`, @@ -34,26 +34,26 @@ const getRequestContext = async ( return request.newContext(options); }; -export const portalAPIHelper = { +export const portalApiHelper = { async post(params: RequestParams) { - console.log(`POST: ${Constants.portal.url}${params.path}\nPayload: ${JSON.stringify(params.data)}`); + console.log(`POST: ${constants.portal.url}${params.path}\nPayload: ${JSON.stringify(params.data)}`); return (await getRequestContext(params)) .post(params.path, { data: params.data }).then(checkAndReturnResponse); }, async put(params: RequestParams) { - console.log(`PUT: ${Constants.portal.url}${params.path}\nPayload: ${JSON.stringify(params.data)}`); + console.log(`PUT: ${constants.portal.url}${params.path}\nPayload: ${JSON.stringify(params.data)}`); return (await getRequestContext(params)) .put(params.path, { data: params.data }).then(checkAndReturnResponse); }, async get(params: RequestParams) { - console.log(`GET: ${Constants.portal.url}${params.path}`); + console.log(`GET: ${constants.portal.url}${params.path}`); return (await getRequestContext(params)).get(params.path).then(checkAndReturnResponse); }, async delete(params: RequestParams) { - console.log(`GET: ${Constants.portal.url}${params.path}`); + console.log(`DELETE: ${constants.portal.url}${params.path}`); return (await getRequestContext(params)).delete(params.path).then(checkAndReturnResponse); }, }; diff --git a/playwright-tests/api/inventory.ts b/playwright-tests/api/inventory.api.ts similarity index 80% rename from playwright-tests/api/inventory.ts rename to playwright-tests/api/inventory.api.ts index 53f27aa5d..96a5f37ba 100644 --- a/playwright-tests/api/inventory.ts +++ b/playwright-tests/api/inventory.api.ts @@ -1,4 +1,4 @@ -import { apiHelper } from './helpers/apiHelper'; +import { apiHelper } from './helpers/api-helper'; interface ListNodes { generic?: NodeDetails[], @@ -12,7 +12,7 @@ interface NodeDetails { machine_id?: string, } -export const inventory = { +export const inventoryApi = { async listNodes(): Promise { return await (await apiHelper.post('v1/inventory/Nodes/List', {})).json() as ListNodes; }, diff --git a/playwright-tests/api/management.ts b/playwright-tests/api/management.api.ts similarity index 84% rename from playwright-tests/api/management.ts rename to playwright-tests/api/management.api.ts index 53b19e383..9df973c7c 100644 --- a/playwright-tests/api/management.ts +++ b/playwright-tests/api/management.api.ts @@ -1,4 +1,4 @@ -import { apiHelper } from '@api/helpers/apiHelper'; +import { apiHelper } from '@api/helpers/api-helper'; export interface ListRoles { roles: Role[] @@ -9,7 +9,7 @@ interface Role { title: string, } -export const management = { +export const managementApi = { listRoles: async (): Promise => { const response = await apiHelper.post('/v1/management/Role/List', {}); return await response.json() as ListRoles; diff --git a/playwright-tests/api/oktaApi.ts b/playwright-tests/api/okta.api.ts similarity index 88% rename from playwright-tests/api/oktaApi.ts rename to playwright-tests/api/okta.api.ts index eefc0ff5c..ea5e68783 100644 --- a/playwright-tests/api/oktaApi.ts +++ b/playwright-tests/api/okta.api.ts @@ -1,14 +1,9 @@ -import { expect, Page } from '@playwright/test'; -import config from '@tests/playwright.config'; -import { PortalUser } from '@helpers/types/PortalUser'; -import * as dotenv from 'dotenv'; -import { Constants } from '@helpers/Constants'; +import { expect } from '@playwright/test'; +import PortalUser from '@helpers/types/portal-user.class'; +import constants from '@helpers/constants'; import axios, { AxiosResponse, Method } from 'axios'; import https from 'https'; -dotenv.config(); -const portalUrl = config.use!.baseURL!; - /** * Implemented HTTP request to OKTA API using provided configuration. * @@ -17,10 +12,10 @@ const portalUrl = config.use!.baseURL!; * @param payload JSON {@code object}; an empty object for get or delete requests */ const oktaRequest = async (method: Method, apiPath: string, payload = {}): Promise => { - console.log(`${method.toUpperCase()}: ${Constants.okta.url}/api/v1${apiPath}\nPayload: ${JSON.stringify(payload)}`); + console.log(`${method.toUpperCase()}: ${constants.okta.url}/api/v1${apiPath}\nPayload: ${JSON.stringify(payload)}`); const response = await axios({ - url: `${Constants.okta.url}/api/v1${apiPath}`, - headers: { 'X-Requested-With': 'XMLHttpRequest', Authorization: Constants.okta.token }, + url: `${constants.okta.url}/api/v1${apiPath}`, + headers: { 'X-Requested-With': 'XMLHttpRequest', Authorization: constants.okta.token }, method, data: payload, httpsAgent: new https.Agent({ rejectUnauthorized: false }), diff --git a/playwright-tests/api/portalApi.ts b/playwright-tests/api/portal.api.ts similarity index 71% rename from playwright-tests/api/portalApi.ts rename to playwright-tests/api/portal.api.ts index 21db0558c..e2753b1fc 100644 --- a/playwright-tests/api/portalApi.ts +++ b/playwright-tests/api/portal.api.ts @@ -1,9 +1,9 @@ -import { PortalUserRoles } from '@helpers/enums/portalUserRoles'; -import { portalAPIHelper } from './helpers/portalApiHelper'; +import { PortalUserRoles } from '@helpers/enums/portal-user-roles'; +import { portalApiHelper } from './helpers/portal-api-helper'; -export const portalAPI = { +export const portalApi = { async getUserAccessToken(username: string, password: string) { - const response = await portalAPIHelper.post({ + const response = await portalApiHelper.post({ path: '/v1/auth/SignIn', data: { email: username, @@ -14,10 +14,10 @@ export const portalAPI = { }, async createOrg(accessToken: string, orgName = 'Test Organization') { - return await portalAPIHelper.post({ + return await portalApiHelper.post({ path: '/v1/orgs', accessToken, - timeout: 60_000, + timeout: 120_000, data: { name: orgName, }, @@ -25,7 +25,7 @@ export const portalAPI = { }, async deleteOrg(accessToken: string, orgId: string) { - return portalAPIHelper.delete({ + return portalApiHelper.delete({ path: `/v1/orgs/${orgId}`, accessToken, data: {}, @@ -33,19 +33,19 @@ export const portalAPI = { }, async getOrg(accessToken: string) { - return await portalAPIHelper.post({ + return await portalApiHelper.post({ accessToken, path: '/v1/orgs:search', }) as { orgs: { id: string }[] }; }, async getOrgDetails(accessToken: string, orgId: string) { - return portalAPIHelper.get({ + return portalApiHelper.get({ accessToken, path: `/v1/orgs/${orgId}`, }); }, async inviteUserToOrg(accessToken: string, orgId: string, username: string, role: PortalUserRoles) { - return portalAPIHelper.post({ + return portalApiHelper.post({ path: `/v1/orgs/${orgId}/members`, accessToken, data: { diff --git a/playwright-tests/api/server.ts b/playwright-tests/api/server.api.ts similarity index 72% rename from playwright-tests/api/server.ts rename to playwright-tests/api/server.api.ts index d49b72768..322679e86 100644 --- a/playwright-tests/api/server.ts +++ b/playwright-tests/api/server.api.ts @@ -1,12 +1,12 @@ -import { apiHelper } from '@api/helpers/apiHelper'; -import Duration from '@helpers/enums/Duration'; -import { PmmVersion } from '@helpers/types/PmmVersion'; +import apiHelper from '@api/helpers/api-helper'; +import Duration from '@helpers/enums/duration'; +import PmmVersion from '@helpers/types/pmm-version.class'; import { expect } from '@playwright/test'; export const server = { /** - * @returns Promise + * @returns Promise */ getPmmVersion: async (): Promise => { const response = await apiHelper.get('/v1/version', { timeout: Duration.ThreeMinutes }); diff --git a/playwright-tests/api/serviceNowApi.ts b/playwright-tests/api/service-now.api.ts similarity index 75% rename from playwright-tests/api/serviceNowApi.ts rename to playwright-tests/api/service-now.api.ts index eb055ac0d..4835e5de7 100644 --- a/playwright-tests/api/serviceNowApi.ts +++ b/playwright-tests/api/service-now.api.ts @@ -1,23 +1,20 @@ -import { ServiceNowResponse, ServiceNowUser } from '@helpers/types/serviceNowResponse.interface'; +import { ServiceNowResponse, ServiceNowUser } from '@helpers/types/service-now-response.interface'; import https from 'https'; -import * as dotenv from 'dotenv'; import axios, { AxiosRequestConfig } from 'axios'; -import { Constants } from '@helpers/Constants'; +import constants from '@helpers/constants'; import { expect } from '@playwright/test'; -dotenv.config(); - const apiConfig: AxiosRequestConfig = { auth: { - username: Constants.serviceNow.username, password: Constants.serviceNow.password, + username: constants.serviceNow.username, password: constants.serviceNow.password, }, httpsAgent: new https.Agent({ rejectUnauthorized: false }), }; -export const serviceNowAPI = { +export const serviceNowApi = { async getServiceNowCredentials(): Promise { - console.log(`POST: ${Constants.serviceNow.devUrl}\nPayload: ${JSON.stringify({})}`); - const response = await axios.post(Constants.serviceNow.devUrl, {}, apiConfig); + console.log(`POST: ${constants.serviceNow.devUrl}\nPayload: ${JSON.stringify({})}`); + const response = await axios.post(constants.serviceNow.devUrl, {}, apiConfig); expect(response.status, `Expected to be 200: ${response.status} ${response.statusText}`).toEqual(200); console.log(`Status: ${response.status} ${response.statusText}`); return { diff --git a/playwright-tests/components/dashboardPanels/nodesOverviewDashboardPanels.ts b/playwright-tests/components/dashboardPanels/nodesOverviewDashboardPanels.ts deleted file mode 100644 index fe136bada..000000000 --- a/playwright-tests/components/dashboardPanels/nodesOverviewDashboardPanels.ts +++ /dev/null @@ -1,89 +0,0 @@ -export const NodesOverviewDashboardPanels = { - // Overview - nodes: { panelId: 326, name: 'Nodes', error: '1' }, - minNodeUptime: { panelId: 375, name: 'Min Node Uptime', error: 'N/A' }, - dBInstances: { panelId: 376, name: 'DB Instances', error: '1' }, // this may vary because of user role, needs to be made better. - totalVirtualCpus: { panelId: 306, name: 'Total Virtual CPUs', error: '0' }, - totalRAM: { panelId: 309, name: 'Total RAM', error: 'N/A' }, - virtualMemoryTotal: { panelId: 310, name: 'Virtual Memory Total', error: 'N/A' }, - diskSpaceTotal: { panelId: 311, name: 'Disk Space Total', error: 'N/A' }, - // Environment Details - regions: { panelId: 64, name: 'Regions', error: 'No data to show' }, - types: { panelId: 66, name: 'Types', error: 'No data to show' }, - environmentNodes: { panelId: 68, name: 'Nodes', error: 'No data to show' }, - // CPU - cpuTopUsage: { panelId: 349, name: 'Top Usage', error: 'N/A' }, - cpuTopSteal: { panelId: 350, name: 'Top Steal', error: 'N/A' }, - cpuTopIOWait: { panelId: 351, name: 'Top I/O Wait', error: 'N/A' }, - cpuTopSaturation: { panelId: 353, name: 'Top Saturation', error: 'N/A' }, - cpuTopSwitches: { panelId: 354, name: 'Top Switches', error: 'N/A' }, - cpuTopLoad: { panelId: 308, name: 'Top Load', error: 'N/A' }, - cpuTopRunnableProcs: { panelId: 352, name: 'Top Runnable Procs', error: 'N/A' }, - cpuTopBlockedProcs: { panelId: 355, name: 'Top Blocked Procs', error: 'N/A' }, - // CPU Details - top5CpuUsage: { panelId: 62, name: 'Top 5 CPU Usage', error: 'No data' }, - cpuUsage: { panelId: 216, name: 'CPU Usage', error: 'No data' }, - top5CpuSteal: { panelId: 329, name: 'Top 5 CPU Steal', error: 'No data' }, - cpuSteal: { panelId: 330, name: 'CPU Steal', error: 'No data' }, - top5CpuIOWait: { panelId: 331, name: 'Top 5 CPU I/O Wait', error: 'No data' }, - cpuIOWait: { panelId: 332, name: 'CPU I/O Wait', error: 'No data' }, - top5CpuSaturation: { panelId: 33, name: 'Top 5 CPU Saturation', error: 'No data' }, - cpuSaturation: { panelId: 313, name: 'CPU Saturation', error: 'No data' }, - top5ContextSwitches: { panelId: 101, name: 'Top 5 Context Switches', error: 'No data' }, - switches: { panelId: 316, name: 'Switches', error: 'No data' }, - top5RunnableProcesses: { panelId: 121, name: 'Top 5 Runnable Processes', error: 'No data' }, - runnableProcesses: { panelId: 318, name: 'Runnable Processes', error: 'No data' }, - top5BlockedProcesses: { panelId: 140, name: 'Top 5 Blocked Processes', error: 'No data' }, - blockedProcesses: { panelId: 320, name: 'Blocked Processes', error: 'No data' }, - // Memory & Swap - minMemoryAvailable: { panelId: 307, name: 'Min Memory Available', error: 'N/A' }, - minVirtualMemoryAvailable : { panelId: 361, name: 'Min Virtual Memory Available ', error: 'N/A' }, - topFileCacheActiveMemory : { panelId: 382, name: 'Top File Cache Active Memory', error: 'N/A' }, - minSwapAvailable : { panelId: 362, name: 'Min Swap Available', error: 'N/A' }, - topSwapReads : { panelId: 360, name: 'Top Swap Reads', error: 'N/A' }, - topSwapWrites : { panelId: 363, name: 'Top Swap Writes', error: 'N/A' }, - // Memory & Swap Details - freeMemoryPercent : { panelId: 336, name: 'Free Memory Percent', error: 'No Data' }, - availableVirtualMemoryPercent : { panelId: 338, name: 'Available Virtual Memory Percent', error: 'No Data' }, - freeSwapSpacePercent : { panelId: 337, name: 'Free Swap Space Percent', error: 'No Data' }, - top5UsedMemory: { panelId: 159, name: 'Top 5 Used Memory', error: 'No Data' }, - top5FreeMemory: { panelId: 29, name: 'Top 5 Free Memory', error: 'No Data' }, - top5UsedVirtualMemory: { panelId: 160, name: 'Top 5 Used Virtual Memory', error: 'No Data' }, - top5AvailableVirtualMemory: { panelId: 6, name: 'Top 5 Available Virtual Memory', error: 'No Data' }, - top5UsedSwapSpace: { panelId: 23, name: 'Top 5 Used Swap Space', error: 'No Data' }, - top5FreeSwapSpace: { panelId: 161, name: 'Top 5 Free Swap Space', error: 'No Data' }, - top5SwapInReads: { panelId: 30, name: 'Top 5 Swap In (Reads)', error: 'No Data' }, - top5SwapOutWrites: { panelId: 162, name: 'Top 5 Swap Out (Writes)', error: 'No Data' }, - // Disk - minFreeSpaceAvailable: { panelId: 312, name: 'Min Free Space Available', error: 'N/A' }, - topIOLoad: { panelId: 364, name: 'Top I/O Load', error: 'N/A' }, - topDiskLatency: { panelId: 365, name: ' Top Disk Latency', error: 'N/A' }, - topDiskOperations: { panelId: 383, name: ' Top Disk Operations', error: 'N/A' }, - topDiskBandwidth: { panelId: 366, name: ' Top Disk Bandwidth', error: 'N/A' }, - topIOActivity: { panelId: 367, name: ' Top I/O Activity', error: 'N/A' }, - // Disk Details - top5DiskIOLoad: { panelId: 51, name: 'Top 5 Disk I/O Load', error: 'No data' }, - diskIOLoad: { panelId: 339, name: 'Disk I/O Load', error: 'No data' }, - top5DiskLatency: { panelId: 167, name: 'Top 5 Disk Latency', error: 'No data' }, - diskLatency: { panelId: 340, name: ' Disk Latency', error: 'No data' }, - top5DiskBandwidth: { panelId: 31, name: 'Top 5 Disk Bandwidth', error: 'No data' }, - diskBandwidth: { panelId: 341, name: ' Disk Bandwidth', error: 'No data' }, - top5IOActivity: { panelId: 342, name: 'Top 5 I/O Activity', error: 'No data' }, - IOActivity: { panelId: 343, name: 'I/O Activity', error: 'No data' }, - // Network - topReceiveNetworkTraffic: { panelId: 370, name: ' Top Receive Network Traffic', error: 'N/A' }, - topTransmitNetworkTraffic: { panelId: 374, name: ' Top Transmit Network Traffic', error: 'N/A' }, - topErrors: { panelId: 371, name: 'Top Errors', error: 'N/A' }, - topDrop: { panelId: 373, name: 'Top Drop', error: 'N/A' }, - topRetransmission: { panelId: 372, name: 'Top Retransmission', error: 'N/A' }, - topRetransmitRate: { panelId: 381, name: 'Top Retransmit rate', error: 'N/A' }, - // Network Details - top5NetworkTraffic: { panelId: 21, name: 'Top 5 Network Traffic', error: 'No data' }, - networkTraffic: { panelId: 303, name: 'Network Traffic', error: 'No data' }, - top5LocalNetworkErrors: { panelId: 52, name: 'Top 5 Local Network Errors', error: 'No data' }, - errors: { panelId: 324, name: 'Errors', error: 'No data' }, - top5TCPRetransmission: { panelId: 53, name: 'Top 5 TCP Retransmission', error: 'No data' }, - retransmission: { panelId: 322, name: 'Retransmission', error: 'No data' }, - top5LocalNetworkDrop: { panelId: 168, name: 'Top 5 Local Network Drop', error: 'No data' }, - drop: { panelId: 323, name: 'Drop', error: 'No data' }, -} \ No newline at end of file diff --git a/playwright-tests/helpers/cli.ts b/playwright-tests/helpers/cli.ts index 0b28c1514..448fd7e6f 100644 --- a/playwright-tests/helpers/cli.ts +++ b/playwright-tests/helpers/cli.ts @@ -1,13 +1,15 @@ -import pmmServerCommands from '@helpers/commandLine/pmmServerCommands'; -import pmmClientCommands from '@helpers/commandLine/pmmClientCommands'; -import systemCommands from '@helpers/commandLine/systemCommands'; +import pmmServerCommands from '@helpers/command-line/pmm-server-commands'; +import pmmClientCommands from '@helpers/command-line/pmm-client-commands'; +import systemCommands from '@helpers/command-line/system-commands'; /** * Command Line Commands collections wrapper. * To use pipe-call in tests, ex: {@code cli.systemCommands.getRunningContainerNames()} */ -export const cli = { +const cli = { pmmClientCommands, pmmServerCommands, systemCommands, }; + +export default cli; diff --git a/playwright-tests/helpers/commandLine/cliHelper.ts b/playwright-tests/helpers/command-line/cliHelper.ts similarity index 77% rename from playwright-tests/helpers/commandLine/cliHelper.ts rename to playwright-tests/helpers/command-line/cliHelper.ts index 55f79de84..c8fe3136f 100644 --- a/playwright-tests/helpers/commandLine/cliHelper.ts +++ b/playwright-tests/helpers/command-line/cliHelper.ts @@ -1,43 +1,43 @@ import { test } from '@playwright/test'; import shell, { ExecOutputReturnValue } from 'shelljs'; -import { CliOutput } from '@helpers/types/CliOutput'; +import ExecReturn from '@helpers/types/exec-return.class'; /** * Shell(sh) exec() wrapper to use outside outside {@link test} - * returns handy {@link CliOutput} object. + * returns handy {@link ExecReturn} object. * * @param command sh command to execute * @return {@link CliOutput} instance */ -export function execute(command: string): CliOutput { +export function execute(command: string): ExecReturn { console.log(`exec: "${command}"`); const obj = shell.exec(command.replace(/(\r\n|\n|\r)/gm, ''), { silent: false }); if (obj.stdout.length > 0) console.log(`Out: "${obj.stdout}"`); if (obj.stderr.length > 0) console.log(`Error: "${obj.stderr}"`); - return new CliOutput(command, obj); + return new ExecReturn(command, obj); } /** - * Shell(sh) exec() wrapper to return handy {@link CliOutput} object. + * Shell(sh) exec() wrapper to return handy {@link ExecReturn} object. * * @param command sh command to execute * @return {@link CliOutput} instance */ -export async function exec(command: string): Promise { +export async function exec(command: string): Promise { return test.step(`Run "${command}" command`, async () => { return execute(command); }); } /** - * Silent Shell(sh) exec() wrapper to return handy {@link CliOutput} object. + * Silent Shell(sh) exec() wrapper to return handy {@link ExecReturn} object. * Provides no logs to skip huge outputs. * * @param command sh command to execute * @return {@link CliOutput} instance */ -export async function execSilent(command: string): Promise { - return new CliOutput( +export async function execSilent(command: string): Promise { + return new ExecReturn( command, await test.step(`Run "${command}" command`, async (): Promise => { return shell.exec(command.replace(/(\r\n|\n|\r)/gm, ''), { silent: false }); diff --git a/playwright-tests/helpers/commandLine/pmmClientCommands.ts b/playwright-tests/helpers/command-line/pmm-client-commands.ts similarity index 100% rename from playwright-tests/helpers/commandLine/pmmClientCommands.ts rename to playwright-tests/helpers/command-line/pmm-client-commands.ts diff --git a/playwright-tests/helpers/commandLine/pmmServerCommands.ts b/playwright-tests/helpers/command-line/pmm-server-commands.ts similarity index 100% rename from playwright-tests/helpers/commandLine/pmmServerCommands.ts rename to playwright-tests/helpers/command-line/pmm-server-commands.ts diff --git a/playwright-tests/helpers/commandLine/systemCommands.ts b/playwright-tests/helpers/command-line/system-commands.ts similarity index 100% rename from playwright-tests/helpers/commandLine/systemCommands.ts rename to playwright-tests/helpers/command-line/system-commands.ts diff --git a/playwright-tests/helpers/Constants.ts b/playwright-tests/helpers/constants.ts similarity index 92% rename from playwright-tests/helpers/Constants.ts rename to playwright-tests/helpers/constants.ts index 0a5cb3748..2fc74f564 100644 --- a/playwright-tests/helpers/Constants.ts +++ b/playwright-tests/helpers/constants.ts @@ -2,7 +2,7 @@ * Constants collection to keep in a single place. * Main function is to handle process.env usage in a single file. */ -export const Constants = { +const constants = { serviceNow: { username: process.env.SERVICENOW_LOGIN || '', password: process.env.SERVICENOW_PASSWORD || '', @@ -18,3 +18,5 @@ export const Constants = { credentialsFile: 'portalCredentials', }, }; + +export default constants; diff --git a/playwright-tests/helpers/enums/Duration.ts b/playwright-tests/helpers/enums/duration.ts similarity index 100% rename from playwright-tests/helpers/enums/Duration.ts rename to playwright-tests/helpers/enums/duration.ts diff --git a/playwright-tests/helpers/enums/portalUserRoles.ts b/playwright-tests/helpers/enums/portal-user-roles.ts similarity index 100% rename from playwright-tests/helpers/enums/portalUserRoles.ts rename to playwright-tests/helpers/enums/portal-user-roles.ts diff --git a/playwright-tests/helpers/fileHelper.ts b/playwright-tests/helpers/file-helper.ts similarity index 100% rename from playwright-tests/helpers/fileHelper.ts rename to playwright-tests/helpers/file-helper.ts diff --git a/playwright-tests/helpers/grafanaHelper.ts b/playwright-tests/helpers/grafana-helper.ts similarity index 100% rename from playwright-tests/helpers/grafanaHelper.ts rename to playwright-tests/helpers/grafana-helper.ts diff --git a/playwright-tests/helpers/portalHelper.ts b/playwright-tests/helpers/portal-helper.ts similarity index 87% rename from playwright-tests/helpers/portalHelper.ts rename to playwright-tests/helpers/portal-helper.ts index 9edb956e0..5e526f1c0 100644 --- a/playwright-tests/helpers/portalHelper.ts +++ b/playwright-tests/helpers/portal-helper.ts @@ -1,8 +1,8 @@ -import { PortalUserRoles } from '@helpers/enums/portalUserRoles'; -import { fileHelper } from '@helpers/fileHelper'; -import { PortalUser } from '@helpers/types/PortalUser'; -import { Constants } from '@helpers/Constants'; -import { ServiceNowResponse } from '@helpers/types/serviceNowResponse.interface'; +import { PortalUserRoles } from '@helpers/enums/portal-user-roles'; +import { fileHelper } from '@helpers/file-helper'; +import PortalUser from '@helpers/types/portal-user.class'; +import constants from '@helpers/constants'; +import { ServiceNowResponse } from '@helpers/types/service-now-response.interface'; import { api } from '@api/api'; /** @@ -18,7 +18,7 @@ export const portalHelper = { let secondAdmin: PortalUser; let technicalUser: PortalUser; - if (fileHelper.fileExists(Constants.portal.credentialsFile)) { + if (fileHelper.fileExists(constants.portal.credentialsFile)) { [firstAdmin, secondAdmin, technicalUser] = portalHelper.loadUsersFromFile(); if (!Object.hasOwn(firstAdmin, 'org')) { const adminToken = await api.portal.getUserAccessToken(firstAdmin.email, firstAdmin.password); @@ -30,7 +30,7 @@ export const portalHelper = { } } else { [firstAdmin, secondAdmin, technicalUser] = await portalHelper.createNewUsers(); - fileHelper.writeToFile(Constants.portal.credentialsFile, JSON.stringify([firstAdmin, secondAdmin, technicalUser])); + fileHelper.writeToFile(constants.portal.credentialsFile, JSON.stringify([firstAdmin, secondAdmin, technicalUser])); } return [firstAdmin, secondAdmin, technicalUser]; }, @@ -39,8 +39,8 @@ export const portalHelper = { * Just a wrapper to hold constants */ loadUsersFromFile: (): [PortalUser, PortalUser, PortalUser, PortalUser] => { - console.log(`Using existing users from file: ${Constants.portal.credentialsFile}`); - return JSON.parse(fileHelper.readFile(Constants.portal.credentialsFile)) as [PortalUser, PortalUser, PortalUser, PortalUser]; + console.log(`Using existing users from file: ${constants.portal.credentialsFile}`); + return JSON.parse(fileHelper.readFile(constants.portal.credentialsFile)) as [PortalUser, PortalUser, PortalUser, PortalUser]; }, /** diff --git a/playwright-tests/helpers/test-helper.ts b/playwright-tests/helpers/test-helper.ts new file mode 100644 index 000000000..4505db28a --- /dev/null +++ b/playwright-tests/helpers/test-helper.ts @@ -0,0 +1,44 @@ +import { test as base } from '@playwright/test'; +import HomeDashboardPage from '@pages/home-dashboard.page'; +import LoginPage from '@pages/login.page'; +import PerconaPlatformPage from '@pages/pmm-settings/PerconaPlatform.page'; +import EntitlementsPage from '@pages/platformPages/entitlements.page'; +import EnvironmentOverviewPage from '@pages/platformPages/environment-overview.page'; +import TicketsPage from '@pages/platformPages/tickets.page'; + +// Declare the types of fixtures. +type PagesCollection = { + entitlementsPage: EntitlementsPage; + environmentOverviewPage: EnvironmentOverviewPage; + homeDashboardPage: HomeDashboardPage; + loginPage: LoginPage; + perconaPlatformPage: PerconaPlatformPage; + ticketsPage: TicketsPage; +}; + +/** + * Test base to provide pages collection to any test. + * Also holds predefined custom test actions. Should be used + */ +export const test = base.extend({ + // TODO: implement lazy init ex: loginPage() to save resources + entitlementsPage: async ({ page }, use) => { + await use(new EntitlementsPage(page)); + }, + environmentOverviewPage: async ({ page }, use) => { + await use(new EnvironmentOverviewPage(page)); + }, + homeDashboardPage: async ({ page }, use) => { + await use(new HomeDashboardPage(page)); + }, + loginPage: async ({ page }, use) => { + await use(new LoginPage(page)); + }, + perconaPlatformPage: async ({ page }, use) => { + await use(new PerconaPlatformPage(page)); + }, + ticketsPage: async ({ page }, use) => { + await use(new TicketsPage(page)); + }, +}); +export { expect } from '@playwright/test'; diff --git a/playwright-tests/helpers/types/CliOutput.ts b/playwright-tests/helpers/types/exec-return.class.ts similarity index 94% rename from playwright-tests/helpers/types/CliOutput.ts rename to playwright-tests/helpers/types/exec-return.class.ts index 3c316b0ca..16009357b 100644 --- a/playwright-tests/helpers/types/CliOutput.ts +++ b/playwright-tests/helpers/types/exec-return.class.ts @@ -1,8 +1,8 @@ import { test, expect } from '@playwright/test'; import { ExecOutputReturnValue } from 'shelljs'; -// TODO: try to refactor it with CliOutput extends ExecOutputReturnValue -export class CliOutput { +// TODO: try to refactor it with ExecReturn extends ExecOutputReturnValue +class ExecReturn { command: string; code: number; stdout: string; @@ -63,3 +63,4 @@ export class CliOutput { return errors.join('\n'); } } +export default ExecReturn; diff --git a/playwright-tests/helpers/types/inviteUser.interface.ts b/playwright-tests/helpers/types/invite-user.interface.ts similarity index 63% rename from playwright-tests/helpers/types/inviteUser.interface.ts rename to playwright-tests/helpers/types/invite-user.interface.ts index 0e86a5aff..7e276cbbe 100644 --- a/playwright-tests/helpers/types/inviteUser.interface.ts +++ b/playwright-tests/helpers/types/invite-user.interface.ts @@ -1,4 +1,4 @@ -import { PortalUserRoles } from '@helpers/enums/portalUserRoles'; +import { PortalUserRoles } from '@helpers/enums/portal-user-roles'; interface InviteUserToOrg { username: string; diff --git a/playwright-tests/helpers/types/PmmVersion.ts b/playwright-tests/helpers/types/pmm-version.class.ts similarity index 94% rename from playwright-tests/helpers/types/PmmVersion.ts rename to playwright-tests/helpers/types/pmm-version.class.ts index 8d07e37be..adbb4e4fa 100644 --- a/playwright-tests/helpers/types/PmmVersion.ts +++ b/playwright-tests/helpers/types/pmm-version.class.ts @@ -2,7 +2,7 @@ * Encapsulates parsing of version sting into split collection of numbers * to reduce and simplify code across tests */ -export class PmmVersion { +class PmmVersion { version: string; public major: number; public minor: number; @@ -23,3 +23,5 @@ export class PmmVersion { return this.version; }; } + +export default PmmVersion; diff --git a/playwright-tests/helpers/types/PortalUser.ts b/playwright-tests/helpers/types/portal-user.class.ts similarity index 90% rename from playwright-tests/helpers/types/PortalUser.ts rename to playwright-tests/helpers/types/portal-user.class.ts index 52a04eb8f..43b9da865 100644 --- a/playwright-tests/helpers/types/PortalUser.ts +++ b/playwright-tests/helpers/types/portal-user.class.ts @@ -1,5 +1,5 @@ import { faker } from '@faker-js/faker'; -import { PortalUserRoles } from '@helpers/enums/portalUserRoles'; +import { PortalUserRoles } from '@helpers/enums/portal-user-roles'; /** * Type holder and generators collection for Portal Users used for tests. @@ -24,3 +24,5 @@ export class PortalUser { this.password = `Aa2${faker.internet.password({ length: 10, pattern: /[a-zA-Z0-9]/ })}`; } } + +export default PortalUser; \ No newline at end of file diff --git a/playwright-tests/helpers/types/serviceNowResponse.interface.ts b/playwright-tests/helpers/types/service-now-response.interface.ts similarity index 100% rename from playwright-tests/helpers/types/serviceNowResponse.interface.ts rename to playwright-tests/helpers/types/service-now-response.interface.ts diff --git a/playwright-tests/pages/QAN/QueryAnalytics.page.ts b/playwright-tests/pages/QAN/QueryAnalytics.page.ts index b0736d209..449d1bc1b 100644 --- a/playwright-tests/pages/QAN/QueryAnalytics.page.ts +++ b/playwright-tests/pages/QAN/QueryAnalytics.page.ts @@ -1,6 +1,6 @@ import { Page } from '@playwright/test'; -import { CommonPage } from '../Common.page'; +import { CommonPage } from '../common.page'; export class QAN extends CommonPage { constructor(page: Page) { diff --git a/playwright-tests/pages/Common.page.ts b/playwright-tests/pages/common.page.ts similarity index 93% rename from playwright-tests/pages/Common.page.ts rename to playwright-tests/pages/common.page.ts index 5641d1f6d..ad3cb33ce 100644 --- a/playwright-tests/pages/Common.page.ts +++ b/playwright-tests/pages/common.page.ts @@ -1,7 +1,7 @@ import { Page } from '@playwright/test'; -import { SideMenu } from '@components/sideMenu'; +import { SideMenu } from '@components/side-menu'; import { Toast } from '@components/toast'; -import OptionsMenu from '@tests/components/optionsMenu'; +import OptionsMenu from '@components/options-menu'; export class CommonPage { constructor(readonly page: Page) {} diff --git a/playwright-tests/pages/dashboards/BaseDashboard.page.ts b/playwright-tests/pages/dashboards/base-dashboard.page.ts similarity index 84% rename from playwright-tests/pages/dashboards/BaseDashboard.page.ts rename to playwright-tests/pages/dashboards/base-dashboard.page.ts index b1c219449..c66e22a8d 100644 --- a/playwright-tests/pages/dashboards/BaseDashboard.page.ts +++ b/playwright-tests/pages/dashboards/base-dashboard.page.ts @@ -1,14 +1,8 @@ -import { expect, Page } from '@playwright/test'; -import Duration from '@helpers/enums/Duration'; -import { CommonPage } from '../Common.page'; +import { expect } from '@playwright/test'; +import Duration from '@helpers/enums/duration'; +import { CommonPage } from '../common.page'; export class BaseDashboard extends CommonPage { - constructor(page: Page) { - super(page); - } - - - private baseDashboardElements = { ...super.getElements(), collapsedPanel: this.page.locator('//*[contains(@class, "dashboard-row--collapsed")]'), @@ -67,12 +61,14 @@ export class BaseDashboard extends CommonPage { openAllPanels = async () => { try { - await this.baseDashboardElements.collapsedPanel.waitFor({ state: 'visible' }); + await this.baseDashboardElements.collapsedPanel.waitFor({ + state: 'visible', + }); } catch (e) { } - const collapsedPanels = await this.baseDashboardElements.collapsedPanel.elementHandles() + const collapsedPanels = await this.baseDashboardElements.collapsedPanel.elementHandles(); for await (const [index, panel] of collapsedPanels.entries()) { - await panel.click() + await panel.click(); } await this.page.keyboard.press('PageDown'); await this.page.waitForTimeout(1000); @@ -86,53 +82,67 @@ export class BaseDashboard extends CommonPage { await this.page.waitForTimeout(1000); await this.page.keyboard.press('PageUp'); await this.page.waitForTimeout(1000); - } + }; waitForPanelToHaveData = async (panelHeader: string, panelId: number, timeout: Duration = Duration.OneMinute) => { await this.openAllPanels(); await this.baseDashboardElements.getPanelByName(panelHeader, panelId).scrollIntoViewIfNeeded(); - await expect(this.baseDashboardElements.getPanelByName(panelHeader, panelId)).not.toContainText('N/A', { ignoreCase: true, timeout }); - await expect(this.baseDashboardElements.getPanelByName(panelHeader, panelId)).not.toContainText('No data', { ignoreCase: true, timeout }); - await expect(this.baseDashboardElements.getPanelByName(panelHeader, panelId)).not.toContainText('Insufficient access permissions', { ignoreCase: true, timeout }); + await expect(this.baseDashboardElements.getPanelByName(panelHeader, panelId)).not.toContainText('N/A', { + ignoreCase: true, timeout, + }); + await expect(this.baseDashboardElements.getPanelByName(panelHeader, panelId)).not.toContainText('No data', { + ignoreCase: true, timeout, + }); + await expect(this.baseDashboardElements.getPanelByName(panelHeader, panelId)).not.toContainText('Insufficient access permissions', { + ignoreCase: true, timeout, + }); await this.page.keyboard.press('PageDown'); - } + }; verifyAllPanelsHaveData = async (panelsWithoutData: number) => { await this.openAllPanels(); - let noDataElements: number = 0; + let noDataElements = 0; const panelData = await this.baseDashboardElements.panelContent.elementHandles(); for await (const [index, panel] of panelData.entries()) { await this.baseDashboardElements.panelContent.nth(index).scrollIntoViewIfNeeded(); try { - await expect(this.baseDashboardElements.panelContent.nth(index)).not.toContainText('N/A', { ignoreCase: true }); - await expect(this.baseDashboardElements.panelContent.nth(index)).not.toContainText('No data', { ignoreCase: true }); - await expect(this.baseDashboardElements.panelContent.nth(index)).not.toContainText('Insufficient access permissions', { ignoreCase: true }); + await expect(this.baseDashboardElements.panelContent.nth(index)).not.toContainText('N/A', { + ignoreCase: true, + }); + await expect(this.baseDashboardElements.panelContent.nth(index)).not.toContainText('No data', { + ignoreCase: true, + }); + await expect(this.baseDashboardElements.panelContent.nth(index)).not.toContainText('Insufficient access permissions', { + ignoreCase: true, + }); } catch (err) { noDataElements++; if (noDataElements > panelsWithoutData) { - throw new Error(`Number of elements without data is greater than expected (${panelsWithoutData})`) + throw new Error(`Number of elements without data is greater than expected (${panelsWithoutData})`); } } await this.page.keyboard.press('PageDown'); } - } + }; public verifyExpectedPanelsShowError = async (expectedPanels: any[]) => { await this.openAllPanels(); const panelData = await this.baseDashboardElements.panelTitle.elementHandles(); for await (const [index, expectedPanel] of expectedPanels.entries()) { const foundPanel = panelData.find(async (panel) => { - return (await panel.textContent()) === expectedPanel.name + return (await panel.textContent()) === expectedPanel.name; }); if (foundPanel) { await this.baseDashboardElements.getPanelByName(expectedPanel.name, expectedPanel.panelId).scrollIntoViewIfNeeded(); - await expect(this.baseDashboardElements.getPanelByName(expectedPanel.name, expectedPanel.panelId)).toContainText(expectedPanel.error, { ignoreCase: true }); + await expect(this.baseDashboardElements.getPanelByName(expectedPanel.name, expectedPanel.panelId)).toContainText(expectedPanel.error, { + ignoreCase: true, + }); await this.page.keyboard.press('PageDown'); } } - } + }; verifyAllPanelsDoesNotHaveData = async () => { await this.openAllPanels(); @@ -145,5 +155,5 @@ export class BaseDashboard extends CommonPage { } await this.page.keyboard.press('PageDown'); } - } + }; } diff --git a/playwright-tests/pages/dashboards/mongo/MongoDBInstanceSummary.page.ts b/playwright-tests/pages/dashboards/mongo/mongo-db-instance-summary.page.ts similarity index 86% rename from playwright-tests/pages/dashboards/mongo/MongoDBInstanceSummary.page.ts rename to playwright-tests/pages/dashboards/mongo/mongo-db-instance-summary.page.ts index 42b949efd..3d1c20a7b 100644 --- a/playwright-tests/pages/dashboards/mongo/MongoDBInstanceSummary.page.ts +++ b/playwright-tests/pages/dashboards/mongo/mongo-db-instance-summary.page.ts @@ -1,6 +1,6 @@ import { Page } from '@playwright/test'; -import RbacTable from '@tests/components/rbacTable'; -import { BaseDashboard } from '../BaseDashboard.page'; +import RbacTable from '@components/rbac-table'; +import { BaseDashboard } from '../base-dashboard.page'; export class MongoDBInstanceSummary extends BaseDashboard { constructor(page: Page) { diff --git a/playwright-tests/pages/dashboards/mysql/MySqlDashboard.page.ts b/playwright-tests/pages/dashboards/mysql/mysql-dashboard.page.ts similarity index 69% rename from playwright-tests/pages/dashboards/mysql/MySqlDashboard.page.ts rename to playwright-tests/pages/dashboards/mysql/mysql-dashboard.page.ts index 9d0c08ed5..0c8b56d69 100644 --- a/playwright-tests/pages/dashboards/mysql/MySqlDashboard.page.ts +++ b/playwright-tests/pages/dashboards/mysql/mysql-dashboard.page.ts @@ -1,13 +1,7 @@ -import { Page } from '@playwright/test'; -import RbacTable from '@tests/components/rbacTable'; -import { BaseDashboard } from '../BaseDashboard.page'; +import { BaseDashboard } from '../base-dashboard.page'; export class MySqlDashboard extends BaseDashboard { - constructor(page: Page) { - super(page); - } - - url = 'graph/d/mysql-instance-overview/mysql-instances-overview?orgId=1&refresh=1m' + url = 'graph/d/mysql-instance-overview/mysql-instances-overview?orgId=1&refresh=1m'; elements = { ...super.getBaseDashboardElements(), @@ -34,5 +28,4 @@ export class MySqlDashboard extends BaseDashboard { links = { ...super.getBaseDashboardLinks(), }; - } diff --git a/playwright-tests/pages/dashboards/nodes/NodesOverviewDashboard.page.ts b/playwright-tests/pages/dashboards/nodes/nodes-overview-dashboard.page.ts similarity index 83% rename from playwright-tests/pages/dashboards/nodes/NodesOverviewDashboard.page.ts rename to playwright-tests/pages/dashboards/nodes/nodes-overview-dashboard.page.ts index be854818d..b805753fd 100644 --- a/playwright-tests/pages/dashboards/nodes/NodesOverviewDashboard.page.ts +++ b/playwright-tests/pages/dashboards/nodes/nodes-overview-dashboard.page.ts @@ -1,6 +1,6 @@ import { expect, Page } from '@playwright/test'; -import { NodesOverviewDashboardPanels } from '@tests/components/dashboardPanels/nodesOverviewDashboardPanels'; -import { BaseDashboard } from '../BaseDashboard.page'; +import { NodesOverviewDashboardPanels } from '@components/dashboards/nodes-overview-dashboard-panels'; +import { BaseDashboard } from '../base-dashboard.page'; export default class NodesOverviewDashboard extends BaseDashboard { constructor(page: Page) { diff --git a/playwright-tests/pages/dashboards/postgresql/PostgresqlInstancesOverview.page.ts b/playwright-tests/pages/dashboards/postgresql/postgresql-iInstances-overview.page.ts similarity index 79% rename from playwright-tests/pages/dashboards/postgresql/PostgresqlInstancesOverview.page.ts rename to playwright-tests/pages/dashboards/postgresql/postgresql-iInstances-overview.page.ts index 9196143aa..791098cad 100644 --- a/playwright-tests/pages/dashboards/postgresql/PostgresqlInstancesOverview.page.ts +++ b/playwright-tests/pages/dashboards/postgresql/postgresql-iInstances-overview.page.ts @@ -1,6 +1,6 @@ import { expect, Page } from '@playwright/test'; -import { NodesOverviewDashboardPanels } from '@tests/components/dashboardPanels/nodesOverviewDashboardPanels'; -import { BaseDashboard } from '../BaseDashboard.page'; +import { NodesOverviewDashboardPanels } from '@components/dashboards/nodes-overview-dashboard-panels'; +import { BaseDashboard } from '../base-dashboard.page'; export default class PostgresqlInstancesOverviewDashboard extends BaseDashboard { constructor(page: Page) { diff --git a/playwright-tests/pages/HomeDashboard.page.ts b/playwright-tests/pages/home-dashboard.page.ts similarity index 79% rename from playwright-tests/pages/HomeDashboard.page.ts rename to playwright-tests/pages/home-dashboard.page.ts index 0fc15440f..e777e9584 100644 --- a/playwright-tests/pages/HomeDashboard.page.ts +++ b/playwright-tests/pages/home-dashboard.page.ts @@ -1,11 +1,11 @@ -import { expect, Page } from '@playwright/test'; -import PmmUpgrade from '@components/pmmUpgrade'; -import UpgradeModal from '@components/upgradeModal'; -import Duration from '@helpers/enums/Duration'; -import PmmMenu from '@tests/components/dasboards/homeDashboard/pmmMenu'; -import { BaseDashboard } from './dashboards/BaseDashboard.page'; - -export default class HomeDashboard extends BaseDashboard { +import { expect } from '@playwright/test'; +import PmmUpgrade from '@components/pmm-upgrade-panel'; +import UpgradeModal from '@components/upgrade-modal'; +import Duration from '@helpers/enums/duration'; +import PmmMenu from '@components/dashboards/pmm-menu'; +import { BaseDashboard } from './dashboards/base-dashboard.page'; + +export default class HomeDashboardPage extends BaseDashboard { pmmUpgrade = new PmmUpgrade(this.page); upgradeModal = new UpgradeModal(this.page); pmmMenu = new PmmMenu(this.page); diff --git a/playwright-tests/pages/SignIn.page.ts b/playwright-tests/pages/login.page.ts similarity index 76% rename from playwright-tests/pages/SignIn.page.ts rename to playwright-tests/pages/login.page.ts index a5159cbee..ca11bdd4f 100644 --- a/playwright-tests/pages/SignIn.page.ts +++ b/playwright-tests/pages/login.page.ts @@ -1,8 +1,9 @@ import { Page } from '@playwright/test'; -import { OktaSignInPage } from '@pages/OktaSignIn.page'; -import { CommonPage } from '@pages/Common.page'; +import { OktaSignInPage } from '@pages/okta-sign-in.page'; +import { CommonPage } from '@pages/common.page'; -export class SignInPage extends CommonPage { +class LoginPage extends CommonPage { + private readonly pagePath = 'graph/login'; constructor(readonly page: Page) { super(page); } @@ -34,6 +35,9 @@ export class SignInPage extends CommonPage { ...super.getLinks(), }; + open = async () => { + await this.page.goto(this.pagePath); + }; oktaLogin = async (username: string, password: string) => { const oktaSignInPage = new OktaSignInPage(this.page); @@ -44,3 +48,4 @@ export class SignInPage extends CommonPage { await oktaSignInPage.buttons.signIn.click(); }; } +export default LoginPage; diff --git a/playwright-tests/pages/OktaSignIn.page.ts b/playwright-tests/pages/okta-sign-in.page.ts similarity index 100% rename from playwright-tests/pages/OktaSignIn.page.ts rename to playwright-tests/pages/okta-sign-in.page.ts diff --git a/playwright-tests/components/configuration/usersTable.ts b/playwright-tests/pages/page-components/configuration/users-table.ts similarity index 93% rename from playwright-tests/components/configuration/usersTable.ts rename to playwright-tests/pages/page-components/configuration/users-table.ts index 3fce10d82..dc34a111a 100644 --- a/playwright-tests/components/configuration/usersTable.ts +++ b/playwright-tests/pages/page-components/configuration/users-table.ts @@ -1,5 +1,5 @@ import { Page } from '@playwright/test'; -import OptionsMenu from '../optionsMenu'; +import OptionsMenu from '@components/options-menu'; export default class UsersTable { constructor(readonly page: Page) {} diff --git a/playwright-tests/pages/page-components/dashboards/nodes-overview-dashboard-panels.ts b/playwright-tests/pages/page-components/dashboards/nodes-overview-dashboard-panels.ts new file mode 100644 index 000000000..fcc86ec59 --- /dev/null +++ b/playwright-tests/pages/page-components/dashboards/nodes-overview-dashboard-panels.ts @@ -0,0 +1,89 @@ +export const NodesOverviewDashboardPanels = { + // Overview + nodes: { panelId: 326, name: 'Nodes', error: '1' }, + minNodeUptime: { panelId: 375, name: 'Min Node Uptime', error: 'N/A' }, + dBInstances: { panelId: 376, name: 'DB Instances', error: '1' }, // this may vary because of user role, needs to be made better. + totalVirtualCpus: { panelId: 306, name: 'Total Virtual CPUs', error: '0' }, + totalRAM: { panelId: 309, name: 'Total RAM', error: 'N/A' }, + virtualMemoryTotal: { panelId: 310, name: 'Virtual Memory Total', error: 'N/A' }, + diskSpaceTotal: { panelId: 311, name: 'Disk Space Total', error: 'N/A' }, + // Environment Details + regions: { panelId: 64, name: 'Regions', error: 'No data to show' }, + types: { panelId: 66, name: 'Types', error: 'No data to show' }, + environmentNodes: { panelId: 68, name: 'Nodes', error: 'No data to show' }, + // CPU + cpuTopUsage: { panelId: 349, name: 'Top Usage', error: 'N/A' }, + cpuTopSteal: { panelId: 350, name: 'Top Steal', error: 'N/A' }, + cpuTopIOWait: { panelId: 351, name: 'Top I/O Wait', error: 'N/A' }, + cpuTopSaturation: { panelId: 353, name: 'Top Saturation', error: 'N/A' }, + cpuTopSwitches: { panelId: 354, name: 'Top Switches', error: 'N/A' }, + cpuTopLoad: { panelId: 308, name: 'Top Load', error: 'N/A' }, + cpuTopRunnableProcs: { panelId: 352, name: 'Top Runnable Procs', error: 'N/A' }, + cpuTopBlockedProcs: { panelId: 355, name: 'Top Blocked Procs', error: 'N/A' }, + // CPU Details + top5CpuUsage: { panelId: 62, name: 'Top 5 CPU Usage', error: 'No data' }, + cpuUsage: { panelId: 216, name: 'CPU Usage', error: 'No data' }, + top5CpuSteal: { panelId: 329, name: 'Top 5 CPU Steal', error: 'No data' }, + cpuSteal: { panelId: 330, name: 'CPU Steal', error: 'No data' }, + top5CpuIOWait: { panelId: 331, name: 'Top 5 CPU I/O Wait', error: 'No data' }, + cpuIOWait: { panelId: 332, name: 'CPU I/O Wait', error: 'No data' }, + top5CpuSaturation: { panelId: 33, name: 'Top 5 CPU Saturation', error: 'No data' }, + cpuSaturation: { panelId: 313, name: 'CPU Saturation', error: 'No data' }, + top5ContextSwitches: { panelId: 101, name: 'Top 5 Context Switches', error: 'No data' }, + switches: { panelId: 316, name: 'Switches', error: 'No data' }, + top5RunnableProcesses: { panelId: 121, name: 'Top 5 Runnable Processes', error: 'No data' }, + runnableProcesses: { panelId: 318, name: 'Runnable Processes', error: 'No data' }, + top5BlockedProcesses: { panelId: 140, name: 'Top 5 Blocked Processes', error: 'No data' }, + blockedProcesses: { panelId: 320, name: 'Blocked Processes', error: 'No data' }, + // Memory & Swap + minMemoryAvailable: { panelId: 307, name: 'Min Memory Available', error: 'N/A' }, + minVirtualMemoryAvailable: { panelId: 361, name: 'Min Virtual Memory Available ', error: 'N/A' }, + topFileCacheActiveMemory: { panelId: 382, name: 'Top File Cache Active Memory', error: 'N/A' }, + minSwapAvailable: { panelId: 362, name: 'Min Swap Available', error: 'N/A' }, + topSwapReads: { panelId: 360, name: 'Top Swap Reads', error: 'N/A' }, + topSwapWrites: { panelId: 363, name: 'Top Swap Writes', error: 'N/A' }, + // Memory & Swap Details + freeMemoryPercent: { panelId: 336, name: 'Free Memory Percent', error: 'No Data' }, + availableVirtualMemoryPercent: { panelId: 338, name: 'Available Virtual Memory Percent', error: 'No Data' }, + freeSwapSpacePercent: { panelId: 337, name: 'Free Swap Space Percent', error: 'No Data' }, + top5UsedMemory: { panelId: 159, name: 'Top 5 Used Memory', error: 'No Data' }, + top5FreeMemory: { panelId: 29, name: 'Top 5 Free Memory', error: 'No Data' }, + top5UsedVirtualMemory: { panelId: 160, name: 'Top 5 Used Virtual Memory', error: 'No Data' }, + top5AvailableVirtualMemory: { panelId: 6, name: 'Top 5 Available Virtual Memory', error: 'No Data' }, + top5UsedSwapSpace: { panelId: 23, name: 'Top 5 Used Swap Space', error: 'No Data' }, + top5FreeSwapSpace: { panelId: 161, name: 'Top 5 Free Swap Space', error: 'No Data' }, + top5SwapInReads: { panelId: 30, name: 'Top 5 Swap In (Reads)', error: 'No Data' }, + top5SwapOutWrites: { panelId: 162, name: 'Top 5 Swap Out (Writes)', error: 'No Data' }, + // Disk + minFreeSpaceAvailable: { panelId: 312, name: 'Min Free Space Available', error: 'N/A' }, + topIOLoad: { panelId: 364, name: 'Top I/O Load', error: 'N/A' }, + topDiskLatency: { panelId: 365, name: ' Top Disk Latency', error: 'N/A' }, + topDiskOperations: { panelId: 383, name: ' Top Disk Operations', error: 'N/A' }, + topDiskBandwidth: { panelId: 366, name: ' Top Disk Bandwidth', error: 'N/A' }, + topIOActivity: { panelId: 367, name: ' Top I/O Activity', error: 'N/A' }, + // Disk Details + top5DiskIOLoad: { panelId: 51, name: 'Top 5 Disk I/O Load', error: 'No data' }, + diskIOLoad: { panelId: 339, name: 'Disk I/O Load', error: 'No data' }, + top5DiskLatency: { panelId: 167, name: 'Top 5 Disk Latency', error: 'No data' }, + diskLatency: { panelId: 340, name: ' Disk Latency', error: 'No data' }, + top5DiskBandwidth: { panelId: 31, name: 'Top 5 Disk Bandwidth', error: 'No data' }, + diskBandwidth: { panelId: 341, name: ' Disk Bandwidth', error: 'No data' }, + top5IOActivity: { panelId: 342, name: 'Top 5 I/O Activity', error: 'No data' }, + IOActivity: { panelId: 343, name: 'I/O Activity', error: 'No data' }, + // Network + topReceiveNetworkTraffic: { panelId: 370, name: ' Top Receive Network Traffic', error: 'N/A' }, + topTransmitNetworkTraffic: { panelId: 374, name: ' Top Transmit Network Traffic', error: 'N/A' }, + topErrors: { panelId: 371, name: 'Top Errors', error: 'N/A' }, + topDrop: { panelId: 373, name: 'Top Drop', error: 'N/A' }, + topRetransmission: { panelId: 372, name: 'Top Retransmission', error: 'N/A' }, + topRetransmitRate: { panelId: 381, name: 'Top Retransmit rate', error: 'N/A' }, + // Network Details + top5NetworkTraffic: { panelId: 21, name: 'Top 5 Network Traffic', error: 'No data' }, + networkTraffic: { panelId: 303, name: 'Network Traffic', error: 'No data' }, + top5LocalNetworkErrors: { panelId: 52, name: 'Top 5 Local Network Errors', error: 'No data' }, + errors: { panelId: 324, name: 'Errors', error: 'No data' }, + top5TCPRetransmission: { panelId: 53, name: 'Top 5 TCP Retransmission', error: 'No data' }, + retransmission: { panelId: 322, name: 'Retransmission', error: 'No data' }, + top5LocalNetworkDrop: { panelId: 168, name: 'Top 5 Local Network Drop', error: 'No data' }, + drop: { panelId: 323, name: 'Drop', error: 'No data' }, +}; diff --git a/playwright-tests/components/dasboards/homeDashboard/pmmMenu.ts b/playwright-tests/pages/page-components/dashboards/pmm-menu.ts similarity index 100% rename from playwright-tests/components/dasboards/homeDashboard/pmmMenu.ts rename to playwright-tests/pages/page-components/dashboards/pmm-menu.ts diff --git a/playwright-tests/components/optionsMenu.ts b/playwright-tests/pages/page-components/options-menu.ts similarity index 100% rename from playwright-tests/components/optionsMenu.ts rename to playwright-tests/pages/page-components/options-menu.ts diff --git a/playwright-tests/components/pmmUpgrade.ts b/playwright-tests/pages/page-components/pmm-upgrade-panel.ts similarity index 97% rename from playwright-tests/components/pmmUpgrade.ts rename to playwright-tests/pages/page-components/pmm-upgrade-panel.ts index 155c489d2..a0040c6af 100644 --- a/playwright-tests/components/pmmUpgrade.ts +++ b/playwright-tests/pages/page-components/pmm-upgrade-panel.ts @@ -1,5 +1,5 @@ import { expect, Page } from '@playwright/test'; -import Duration from '@helpers/enums/Duration'; +import Duration from '@helpers/enums/duration'; export default class PmmUpgrade { constructor(readonly page: Page) {} diff --git a/playwright-tests/components/rbacTable.ts b/playwright-tests/pages/page-components/rbac-table.ts similarity index 100% rename from playwright-tests/components/rbacTable.ts rename to playwright-tests/pages/page-components/rbac-table.ts diff --git a/playwright-tests/components/sideMenu.ts b/playwright-tests/pages/page-components/side-menu.ts similarity index 87% rename from playwright-tests/components/sideMenu.ts rename to playwright-tests/pages/page-components/side-menu.ts index 07c1131d7..63fdbeb99 100644 --- a/playwright-tests/components/sideMenu.ts +++ b/playwright-tests/pages/page-components/side-menu.ts @@ -1,5 +1,5 @@ import { Page } from '@playwright/test'; -import ConfigurationMenu from './sideMenus/configurationMenu'; +import ConfigurationMenu from '@components/sideMenus/configuration-menu'; export class SideMenu { constructor(readonly page: Page) {} diff --git a/playwright-tests/components/sideMenus/configurationMenu.ts b/playwright-tests/pages/page-components/sideMenus/configuration-menu.ts similarity index 100% rename from playwright-tests/components/sideMenus/configurationMenu.ts rename to playwright-tests/pages/page-components/sideMenus/configuration-menu.ts diff --git a/playwright-tests/components/table.ts b/playwright-tests/pages/page-components/table.ts similarity index 100% rename from playwright-tests/components/table.ts rename to playwright-tests/pages/page-components/table.ts diff --git a/playwright-tests/components/toast.ts b/playwright-tests/pages/page-components/toast.ts similarity index 95% rename from playwright-tests/components/toast.ts rename to playwright-tests/pages/page-components/toast.ts index 7e36c597e..029601f2d 100644 --- a/playwright-tests/components/toast.ts +++ b/playwright-tests/pages/page-components/toast.ts @@ -1,6 +1,5 @@ import { Page, expect, Locator } from '@playwright/test'; -import Duration from '@helpers/enums/Duration'; -import config from '@tests/playwright.config'; +import config from '@root/playwright.config'; export class Toast { constructor(readonly page: Page) { } diff --git a/playwright-tests/components/upgradeModal.ts b/playwright-tests/pages/page-components/upgrade-modal.ts similarity index 94% rename from playwright-tests/components/upgradeModal.ts rename to playwright-tests/pages/page-components/upgrade-modal.ts index 8f4fc299a..afe4aca4d 100644 --- a/playwright-tests/components/upgradeModal.ts +++ b/playwright-tests/pages/page-components/upgrade-modal.ts @@ -1,5 +1,5 @@ import { Page } from '@playwright/test'; -import { CommonPage } from '@pages/Common.page'; +import { CommonPage } from '@pages/common.page'; export default class UpgradeModal extends CommonPage { constructor(page: Page) { diff --git a/playwright-tests/pages/platformPages/Entitlements.page.ts b/playwright-tests/pages/platformPages/entitlements.page.ts similarity index 93% rename from playwright-tests/pages/platformPages/Entitlements.page.ts rename to playwright-tests/pages/platformPages/entitlements.page.ts index 9a25165dd..41143fd0d 100644 --- a/playwright-tests/pages/platformPages/Entitlements.page.ts +++ b/playwright-tests/pages/platformPages/entitlements.page.ts @@ -1,5 +1,5 @@ import { Page } from '@playwright/test'; -import { CommonPage } from '@pages/Common.page'; +import { CommonPage } from '@pages/common.page'; export default class EntitlementsPage extends CommonPage { constructor(page: Page) { diff --git a/playwright-tests/pages/platformPages/EnvironmentOverview.page.ts b/playwright-tests/pages/platformPages/environment-overview.page.ts similarity index 85% rename from playwright-tests/pages/platformPages/EnvironmentOverview.page.ts rename to playwright-tests/pages/platformPages/environment-overview.page.ts index 240fc571b..866b04582 100644 --- a/playwright-tests/pages/platformPages/EnvironmentOverview.page.ts +++ b/playwright-tests/pages/platformPages/environment-overview.page.ts @@ -1,11 +1,6 @@ -import { Page } from '@playwright/test'; -import { CommonPage } from '@pages/Common.page'; +import { CommonPage } from '@pages/common.page'; export default class EnvironmentOverview extends CommonPage { - constructor(page: Page) { - super(page); - } - environmentOverviewUrl = 'graph/entitlements'; environmentOverviewContainer = this.page.getByTestId('page-wrapper-environment-overview'); diff --git a/playwright-tests/pages/platformPages/Tickets.page.ts b/playwright-tests/pages/platformPages/tickets.page.ts similarity index 94% rename from playwright-tests/pages/platformPages/Tickets.page.ts rename to playwright-tests/pages/platformPages/tickets.page.ts index 752a4b7f6..6e0fcf045 100644 --- a/playwright-tests/pages/platformPages/Tickets.page.ts +++ b/playwright-tests/pages/platformPages/tickets.page.ts @@ -1,5 +1,5 @@ import { Page } from '@playwright/test'; -import { CommonPage } from '@pages/Common.page'; +import { CommonPage } from '@pages/common.page'; export default class TicketsPage extends CommonPage { constructor(page: Page) { diff --git a/playwright-tests/pages/pmmSettings/PerconaPlatform.page.ts b/playwright-tests/pages/pmm-settings/PerconaPlatform.page.ts similarity index 94% rename from playwright-tests/pages/pmmSettings/PerconaPlatform.page.ts rename to playwright-tests/pages/pmm-settings/PerconaPlatform.page.ts index 8f4a5d603..334ed170f 100644 --- a/playwright-tests/pages/pmmSettings/PerconaPlatform.page.ts +++ b/playwright-tests/pages/pmm-settings/PerconaPlatform.page.ts @@ -1,11 +1,6 @@ -import { Page } from '@playwright/test'; -import { CommonPage } from '@pages/Common.page'; - -export default class PerconaPlatform extends CommonPage { - constructor(page: Page) { - super(page); - } +import { CommonPage } from '@pages/common.page'; +export default class PerconaPlatformPage extends CommonPage { perconaPlatformURL = 'graph/settings/percona-platform'; perconaPlatformContainer = this.page.getByTestId('connect-form'); connectedContainer = this.page.getByTestId('connected-wrapper'); @@ -44,7 +39,7 @@ export default class PerconaPlatform extends CommonPage { requiredField: 'Required field', createPerconaAccount: 'Create a Percona account', validateConnection: 'Validate Platform connection', - connect: 'Connect' + connect: 'Connect', }; buttons = { diff --git a/playwright-tests/pages/pmmSettings/AdvancedSettings.page.ts b/playwright-tests/pages/pmm-settings/advanced-settings.page.ts similarity index 92% rename from playwright-tests/pages/pmmSettings/AdvancedSettings.page.ts rename to playwright-tests/pages/pmm-settings/advanced-settings.page.ts index e3bfef5af..4d9d3efba 100644 --- a/playwright-tests/pages/pmmSettings/AdvancedSettings.page.ts +++ b/playwright-tests/pages/pmm-settings/advanced-settings.page.ts @@ -1,5 +1,5 @@ import { Page } from '@playwright/test'; -import { CommonPage } from '@pages/Common.page'; +import { CommonPage } from '@pages/common.page'; export default class AdvancedSettings extends CommonPage { constructor(page: Page) { diff --git a/playwright-tests/pages/serverAdmin/NewUser.page.ts b/playwright-tests/pages/serverAdmin/NewUser.page.ts index a972c6d1d..166f4ca74 100644 --- a/playwright-tests/pages/serverAdmin/NewUser.page.ts +++ b/playwright-tests/pages/serverAdmin/NewUser.page.ts @@ -1,5 +1,5 @@ import { Page } from '@playwright/test'; -import { CommonPage } from '../Common.page'; +import { CommonPage } from '../common.page'; export class NewUserPage extends CommonPage { constructor(page: Page) { diff --git a/playwright-tests/playwright.config.ts b/playwright-tests/playwright.config.ts index 3796dfe97..5c7375ade 100644 --- a/playwright-tests/playwright.config.ts +++ b/playwright-tests/playwright.config.ts @@ -1,7 +1,7 @@ import type { PlaywrightTestConfig } from '@playwright/test'; import { devices } from '@playwright/test'; import * as dotenv from 'dotenv'; -import Duration from '@helpers/enums/Duration'; +import Duration from '@helpers/enums/duration'; /** * Read environment variables from file. diff --git a/playwright-tests/tests/configuration/api/settings.ts b/playwright-tests/tests/configuration/api/settings.api.ts similarity index 89% rename from playwright-tests/tests/configuration/api/settings.ts rename to playwright-tests/tests/configuration/api/settings.api.ts index 1eb32be83..41f53bf17 100644 --- a/playwright-tests/tests/configuration/api/settings.ts +++ b/playwright-tests/tests/configuration/api/settings.api.ts @@ -1,10 +1,13 @@ -import { apiHelper, Settings } from '@api/helpers/apiHelper'; +import apiHelper from '@api/helpers/api-helper'; import { APIResponse } from 'playwright-core'; -import {string} from "yaml/dist/schema/common/string"; const PATH_GET = 'v1/Settings/Get'; const PATH_CHANGE = 'v1/Settings/Change'; +export interface Settings { + pmm_public_address: string; +} + export enum SettingProperty { bm = 'backup_management_enabled', } @@ -13,7 +16,7 @@ type SettingObject = { settings: { [key: string]: never }, }; -export const settings = { +export const settingsApi = { /** * Looks up a single Settings Property from returned. * diff --git a/playwright-tests/tests/configuration/defaultSettings.spec.ts b/playwright-tests/tests/configuration/defaultSettings.spec.ts index 6c1c5d8d3..d8be4a096 100644 --- a/playwright-tests/tests/configuration/defaultSettings.spec.ts +++ b/playwright-tests/tests/configuration/defaultSettings.spec.ts @@ -1,7 +1,7 @@ import { api } from '@api/api'; -import { PmmVersion } from '@helpers/types/PmmVersion'; +import PmmVersion from '@helpers/types/pmm-version.class'; import { expect, test } from '@playwright/test'; -import { SettingProperty } from '@tests/tests/configuration/api/settings'; +import { SettingProperty } from '@root/tests/configuration/api/settings.api'; test.describe('Default Settings tests', async () => { test.describe.configure({ diff --git a/playwright-tests/tests/configuration/pages/Configuration.page.ts b/playwright-tests/tests/configuration/pages/configuration.page.ts similarity index 95% rename from playwright-tests/tests/configuration/pages/Configuration.page.ts rename to playwright-tests/tests/configuration/pages/configuration.page.ts index 3642b8ab3..41ffc16c7 100644 --- a/playwright-tests/tests/configuration/pages/Configuration.page.ts +++ b/playwright-tests/tests/configuration/pages/configuration.page.ts @@ -1,4 +1,4 @@ -import { CommonPage } from '@pages/Common.page'; +import { CommonPage } from '@pages/common.page'; export class ConfigurationPage extends CommonPage { private configurationElements = { diff --git a/playwright-tests/tests/configuration/pages/CreateRole.page.ts b/playwright-tests/tests/configuration/pages/create-role.page.ts similarity index 97% rename from playwright-tests/tests/configuration/pages/CreateRole.page.ts rename to playwright-tests/tests/configuration/pages/create-role.page.ts index 5c2cb1208..b502efff2 100644 --- a/playwright-tests/tests/configuration/pages/CreateRole.page.ts +++ b/playwright-tests/tests/configuration/pages/create-role.page.ts @@ -1,4 +1,4 @@ -import { CommonPage } from '@pages/Common.page'; +import { CommonPage } from '@pages/common.page'; interface CreateRole { roleName: string, diff --git a/playwright-tests/tests/configuration/pages/Rbac.page.ts b/playwright-tests/tests/configuration/pages/rbac.page.ts similarity index 84% rename from playwright-tests/tests/configuration/pages/Rbac.page.ts rename to playwright-tests/tests/configuration/pages/rbac.page.ts index f103bb6f4..3e13daf62 100644 --- a/playwright-tests/tests/configuration/pages/Rbac.page.ts +++ b/playwright-tests/tests/configuration/pages/rbac.page.ts @@ -1,5 +1,5 @@ -import RbacTable from '@components/rbacTable'; -import { ConfigurationPage } from './Configuration.page'; +import RbacTable from '@components/rbac-table'; +import { ConfigurationPage } from './configuration.page'; export class RbacPage extends ConfigurationPage { url = 'graph/roles'; diff --git a/playwright-tests/tests/configuration/pages/UsersConfiguration.page.ts b/playwright-tests/tests/configuration/pages/users-configuration.page.ts similarity index 90% rename from playwright-tests/tests/configuration/pages/UsersConfiguration.page.ts rename to playwright-tests/tests/configuration/pages/users-configuration.page.ts index fd1efb49d..8a67fec6c 100644 --- a/playwright-tests/tests/configuration/pages/UsersConfiguration.page.ts +++ b/playwright-tests/tests/configuration/pages/users-configuration.page.ts @@ -1,6 +1,6 @@ import { expect } from '@playwright/test'; -import UsersTable from '@tests/components/configuration/usersTable'; -import { ConfigurationPage } from './Configuration.page'; +import UsersTable from '@components/configuration/users-table'; +import { ConfigurationPage } from './configuration.page'; export class UsersConfigurationPage extends ConfigurationPage { url = 'graph/org/users'; diff --git a/playwright-tests/tests/inventory/inventory.spec.ts b/playwright-tests/tests/inventory/inventory.spec.ts index 4cca5d74e..04b3d5e51 100644 --- a/playwright-tests/tests/inventory/inventory.spec.ts +++ b/playwright-tests/tests/inventory/inventory.spec.ts @@ -1,17 +1,17 @@ import { expect, test } from '@playwright/test'; -import apiHelper from '@tests/api/helpers/apiHelper'; -import { NodeDetails } from '@tests/tests/inventory/components/nodesTable'; -import { ServiceDetails } from '@tests/tests/inventory/components/servicesTable'; -import cli from '@helpers/commandLine/cliHelper'; -import Duration from '@helpers/enums/Duration'; -import grafanaHelper from '@helpers/grafanaHelper'; -import { MongoDBInstanceSummary } from '@tests/pages/dashboards/mongo/MongoDBInstanceSummary.page'; -import HomeDashboard from '@tests/pages/HomeDashboard.page'; -import { AddServicePage } from '@tests/tests/inventory/pages/AddService.page'; -import { NodesPage } from '@tests/tests/inventory/pages/Nodes.page'; -import { ServicesPage } from '@tests/tests/inventory/pages/Services.page'; -import { QAN } from '@tests/pages/QAN/QueryAnalytics.page'; -import { api } from '@tests/api/api'; +import apiHelper from '@api/helpers/api-helper'; +import { NodeDetails } from '@tests/inventory/pages/components/nodes-table'; +import { ServiceDetails } from '@tests/inventory/pages/components/services-table'; +import cli from '@helpers/cli'; +import Duration from '@helpers/enums/duration'; +import grafanaHelper from '@helpers/grafana-helper'; +import { MongoDBInstanceSummary } from '@pages/dashboards/mongo/mongo-db-instance-summary.page'; +import HomeDashboardPage from '@pages/home-dashboard.page'; +import { AddServicePage } from '@tests/inventory/pages/add-service.page'; +import { NodesPage } from '@tests/inventory/pages/nodes.page'; +import { ServicesPage } from '@tests/inventory/pages/services.page'; +import { QAN } from '@pages/QAN/QueryAnalytics.page'; +import { api } from '@api/api'; test.describe('Spec file for PMM inventory tests.', async () => { const mongoLocalService: ServiceDetails = { @@ -52,7 +52,7 @@ test.describe('Spec file for PMM inventory tests.', async () => { test('PMM-T1669 Verify PMM Inventory redesign : Layout & Services @inventory @inventory-pre-upgrade @inventory-post-upgrade', async ({ page }) => { test.skip(pmmVersion < 37, 'Test is for versions 2.37.0+'); const servicesPage = new ServicesPage(page); - const homeDashboard = new HomeDashboard(page); + const homeDashboard = new HomeDashboardPage(page); const mongoDBInstanceSummary = new MongoDBInstanceSummary(page); const qan = new QAN(page); diff --git a/playwright-tests/tests/inventory/pages/AddService.page.ts b/playwright-tests/tests/inventory/pages/add-service.page.ts similarity index 96% rename from playwright-tests/tests/inventory/pages/AddService.page.ts rename to playwright-tests/tests/inventory/pages/add-service.page.ts index 8a148e8a7..ea8cf0669 100644 --- a/playwright-tests/tests/inventory/pages/AddService.page.ts +++ b/playwright-tests/tests/inventory/pages/add-service.page.ts @@ -1,5 +1,5 @@ import { expect, Page } from '@playwright/test'; -import { CommonPage } from '@pages/Common.page'; +import { CommonPage } from '@pages/common.page'; export class AddServicePage extends CommonPage { url = 'graph/add-instance'; diff --git a/playwright-tests/tests/inventory/components/agentsTable.ts b/playwright-tests/tests/inventory/pages/components/agents-table.ts similarity index 98% rename from playwright-tests/tests/inventory/components/agentsTable.ts rename to playwright-tests/tests/inventory/pages/components/agents-table.ts index 9da64dbc4..77d0d790d 100644 --- a/playwright-tests/tests/inventory/components/agentsTable.ts +++ b/playwright-tests/tests/inventory/pages/components/agents-table.ts @@ -1,5 +1,5 @@ import { ElementHandle, expect } from '@playwright/test'; -import Table from '../../../components/table'; +import Table from '@components/table'; export default class AgentsTable extends Table { private dropdownMenu = this.page.locator('//div[@data-testid="dropdown-menu-menu"]'); diff --git a/playwright-tests/tests/inventory/components/confirmDeleteModal.ts b/playwright-tests/tests/inventory/pages/components/confirm-delete-modal.ts similarity index 100% rename from playwright-tests/tests/inventory/components/confirmDeleteModal.ts rename to playwright-tests/tests/inventory/pages/components/confirm-delete-modal.ts diff --git a/playwright-tests/tests/inventory/components/nodesTable.ts b/playwright-tests/tests/inventory/pages/components/nodes-table.ts similarity index 98% rename from playwright-tests/tests/inventory/components/nodesTable.ts rename to playwright-tests/tests/inventory/pages/components/nodes-table.ts index 53257d555..7313970fe 100644 --- a/playwright-tests/tests/inventory/components/nodesTable.ts +++ b/playwright-tests/tests/inventory/pages/components/nodes-table.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import Table from '../../../components/table'; +import Table from '@components/table'; export interface NodeDetails { status?: string; diff --git a/playwright-tests/tests/inventory/components/servicesTable.ts b/playwright-tests/tests/inventory/pages/components/services-table.ts similarity index 97% rename from playwright-tests/tests/inventory/components/servicesTable.ts rename to playwright-tests/tests/inventory/pages/components/services-table.ts index 4258f0cde..c72e59d23 100644 --- a/playwright-tests/tests/inventory/components/servicesTable.ts +++ b/playwright-tests/tests/inventory/pages/components/services-table.ts @@ -1,6 +1,6 @@ import { expect, Page } from '@playwright/test'; -import Table from '../../../components/table'; -import AgentsTable from './agentsTable'; +import Table from '@components/table'; +import AgentsTable from './agents-table'; export interface ServiceDetails { serviceName: string; diff --git a/playwright-tests/tests/inventory/pages/Inventory.page.ts b/playwright-tests/tests/inventory/pages/inventory.page.ts similarity index 89% rename from playwright-tests/tests/inventory/pages/Inventory.page.ts rename to playwright-tests/tests/inventory/pages/inventory.page.ts index a1ebc90f9..3564f506c 100644 --- a/playwright-tests/tests/inventory/pages/Inventory.page.ts +++ b/playwright-tests/tests/inventory/pages/inventory.page.ts @@ -1,5 +1,5 @@ -import { CommonPage } from '@pages/Common.page'; -import ConfirmDeleteModal from '../components/confirmDeleteModal'; +import { CommonPage } from '@pages/common.page'; +import ConfirmDeleteModal from '@tests/inventory/pages/components/confirm-delete-modal'; export class InventoryPage extends CommonPage { confirmDeleteModal = new ConfirmDeleteModal(this.page); diff --git a/playwright-tests/tests/inventory/pages/Nodes.page.ts b/playwright-tests/tests/inventory/pages/nodes.page.ts similarity index 82% rename from playwright-tests/tests/inventory/pages/Nodes.page.ts rename to playwright-tests/tests/inventory/pages/nodes.page.ts index f5f0f92f8..d1d671522 100644 --- a/playwright-tests/tests/inventory/pages/Nodes.page.ts +++ b/playwright-tests/tests/inventory/pages/nodes.page.ts @@ -1,6 +1,6 @@ import { Page } from '@playwright/test'; -import NodesTable from '@tests/tests/inventory/components/nodesTable'; -import { InventoryPage } from './Inventory.page'; +import NodesTable from '@tests/inventory/pages/components/nodes-table'; +import { InventoryPage } from './inventory.page'; export class NodesPage extends InventoryPage { url = 'graph/inventory/nodes'; diff --git a/playwright-tests/tests/inventory/pages/Services.page.ts b/playwright-tests/tests/inventory/pages/services.page.ts similarity index 85% rename from playwright-tests/tests/inventory/pages/Services.page.ts rename to playwright-tests/tests/inventory/pages/services.page.ts index 121bbb25b..0bc1972a4 100644 --- a/playwright-tests/tests/inventory/pages/Services.page.ts +++ b/playwright-tests/tests/inventory/pages/services.page.ts @@ -1,7 +1,7 @@ import { expect } from '@playwright/test'; -import ServicesTable from '@tests/tests/inventory/components/servicesTable'; -import { InventoryPage } from './Inventory.page'; -import AgentsTable from '../components/agentsTable'; +import ServicesTable from '@tests/inventory/pages/components/services-table'; +import { InventoryPage } from './inventory.page'; +import AgentsTable from '@tests/inventory/pages/components/agents-table'; export class ServicesPage extends InventoryPage { url = 'graph/inventory/services'; diff --git a/playwright-tests/tests/portal/connectPMM.spec.ts b/playwright-tests/tests/portal/connectPMM.spec.ts deleted file mode 100644 index 6bf5d6d60..000000000 --- a/playwright-tests/tests/portal/connectPMM.spec.ts +++ /dev/null @@ -1,163 +0,0 @@ -import { expect, test } from '@playwright/test'; -import { apiHelper } from '@api/helpers/apiHelper'; -import { portalAPI } from '@api/portalApi'; -import Duration from '@helpers/enums/Duration'; -import grafanaHelper from '@helpers/grafanaHelper'; -import HomeDashboard from '@pages/HomeDashboard.page'; -import PerconaPlatform from '@pages/pmmSettings/PerconaPlatform.page'; -import { SignInPage } from '@pages/SignIn.page'; -import { PortalUser } from '@helpers/types/PortalUser'; -import { api } from '@api/api'; -import { portalHelper } from '@helpers/portalHelper'; - -test.describe('Spec file for connecting PMM to the portal', async () => { - test.describe.configure({ retries: 0 }); - let pmmVersion: number; - let firstAdmin: PortalUser; - let secondAdmin: PortalUser; - let technicalUser: PortalUser; - - test.beforeAll(async () => { - pmmVersion = (await api.pmm.serverV1.getPmmVersion()).minor; - [firstAdmin, secondAdmin, technicalUser] = portalHelper.loadUsersFromFile(); - }); - - test.beforeEach(async ({ page }) => { - await apiHelper.confirmTour(page); - await page.goto('/'); - }); - - test('PMM-T809 PMM-T398 Verify Percona Platform elements on PMM Settings Page @portal @pre-pmm-portal-upgrade', async ({ page }) => { - test.skip(pmmVersion < 27, 'This test is for PMM version 2.27.0 and higher'); - const platformPage = new PerconaPlatform(page); - - await test.step('1. Open Percona Platform tab in PMM Settings', async () => { - await grafanaHelper.authorize(page); - await page.goto(platformPage.perconaPlatformURL); - await expect(platformPage.perconaPlatformContainer).toBeVisible(); - - if (pmmVersion >= 35) { - await expect(platformPage.elements.header_2_35).toBeVisible(); - } else { - // TODO: find out what works best .waitFor of expect - await page.getByText(platformPage.labels.header).waitFor({ - state: 'visible', - }); - } - }); - - await test.step('2. Verify all required element are displayed.', async () => { - if (pmmVersion >= 35) { - await expect(platformPage.elements.pmmServerIdHeader).toHaveText(platformPage.labels.pmmServerId_35); - } else { - await expect(platformPage.elements.pmmServerIdHeader).toHaveText(platformPage.labels.pmmServerId); - } - - await expect(platformPage.elements.pmmServerNameHeader).toHaveText(platformPage.labels.pmmServerName); - await expect(platformPage.elements.accessTokenHeader).toHaveText(platformPage.labels.accessToken); - if (pmmVersion >= 35) { - await expect(platformPage.buttons.createPerconaAccount).toHaveAttribute('href', platformPage.links.portalLogin); - await expect(platformPage.buttons.connect).toHaveText(platformPage.labels.validateConnection); - } else { - await expect(platformPage.buttons.connect).toHaveText(platformPage.labels.connect); - } - - if (pmmVersion >= 35) { - await expect(platformPage.buttons.getToken35).toHaveAttribute('href', platformPage.links.portalProfile); - } else if (pmmVersion > 29 && pmmVersion < 35) { - await expect(platformPage.buttons.getToken).toHaveAttribute('href', platformPage.links.portalProfile); - } else { - await expect(platformPage.buttons.getToken).toHaveAttribute('href', platformPage.links.platformProfile); - } - }); - - await test.step('3. Verify that pmm server name and access token are required.', async () => { - await platformPage.fields.pmmServerName.focus(); - await platformPage.fields.accessToken.focus(); - await platformPage.buttons.connect.click({ - force: true, - }); - await expect(platformPage.elements.pmmServerNameError).toHaveText(platformPage.labels.requiredField); - await expect(platformPage.elements.accessTokenError).toHaveText(platformPage.labels.requiredField); - }); - - await test.step('4. Verify user can connect to the portal only when server name and access token are valid.', async () => { - await platformPage.fields.pmmServerName.type('Some Name'); - await platformPage.fields.accessToken.type('Some Token'); - await expect(platformPage.buttons.connect).toBeEnabled(); - }); - }); - - test('PMM-T1224 Verify user is notified about using old PMM version while trying to connect to Portal @portal @pre-pmm-portal-upgrade @post-pmm-portal-upgrade', async ({ page }) => { - test.skip(pmmVersion > 26, 'This test is for PMM version 2.26.0 and lower'); - const platformPage = new PerconaPlatform(page); - - await grafanaHelper.authorize(page); - await page.goto(platformPage.perconaPlatformURL); - await platformPage.fields.pmmServerName.type(`Test Server ${Date.now()}`); - await platformPage.fields.email.type(firstAdmin.email); - await platformPage.fields.password.type(firstAdmin.password); - await platformPage.buttons.connect.click(); - await platformPage.toast.checkToastMessage(platformPage.messages.oldPmmVersionError); - }); - - test('PMM-T1097 Verify PMM server is connected to Portal @not-ui-pipeline @portal @pre-pmm-portal-upgrade', async ({ page }) => { - test.skip(pmmVersion < 27, 'This test is for PMM version 2.27.0 and higher'); - const platformPage = new PerconaPlatform(page); - - await test.step('1. Open Percona Platform tab in PMM Settings', async () => { - await grafanaHelper.authorize(page); - await page.goto(platformPage.perconaPlatformURL); - await platformPage.perconaPlatformContainer.waitFor({ - state: 'visible', - }); - }); - - await test.step('2. Connect PMM to the Portal', async () => { - const adminToken = await portalAPI.getUserAccessToken(firstAdmin.email, firstAdmin.password); - - // pmm address is not set automatically in older pmms. - await platformPage.connectToPortal(adminToken, `Test Server ${Date.now()}`, true); - }); - }); - - test('PMM-T1098 Verify All org users can login in connected PMM server @not-ui-pipeline @portal @pre-pmm-portal-upgrade @post-pmm-portal-upgrade', async ({ - page, - baseURL, - context, - }) => { - test.skip(pmmVersion < 27, 'This test is for PMM version 2.27.0 and higher'); - const signInPage = new SignInPage(page); - const homeDashboard = new HomeDashboard(page); - - await test.step('1. Login as admin user that created the org.', async () => { - await signInPage.oktaLogin(firstAdmin.email, firstAdmin.password); - await homeDashboard.pmmUpgrade.containers.upgradeContainer.waitFor({ - state: 'visible', timeout: Duration.OneMinute, - }); - await expect(page).toHaveURL(`${baseURL}/${signInPage.landingUrl}`); - await context.clearCookies(); - await page.reload(); - }); - - await test.step('1. Login as admin user that was invited to the org.', async () => { - await signInPage.oktaLogin(secondAdmin.email, secondAdmin.password); - await homeDashboard.pmmUpgrade.containers.upgradeContainer.waitFor({ - state: 'visible', timeout: Duration.OneMinute, - }); - await expect(page).toHaveURL(`${baseURL}/${signInPage.landingUrl}`); - await context.clearCookies(); - await page.reload(); - }); - - await test.step('1. Login as technical user that was invited to the org.', async () => { - await signInPage.oktaLogin(technicalUser.email, technicalUser.password); - await homeDashboard.pmmUpgrade.containers.upgradeContainer.waitFor({ - state: 'visible', timeout: Duration.OneMinute, - }); - await expect(page).toHaveURL(`${baseURL}/${signInPage.landingUrl}`); - await context.clearCookies(); - await page.reload(); - }); - }); -}); diff --git a/playwright-tests/tests/portal/connectPmm.spec.ts b/playwright-tests/tests/portal/connectPmm.spec.ts new file mode 100644 index 000000000..a5fc58f87 --- /dev/null +++ b/playwright-tests/tests/portal/connectPmm.spec.ts @@ -0,0 +1,170 @@ +import { expect, test } from '@helpers/test-helper'; +import apiHelper from '@api/helpers/api-helper'; +import { portalApi } from '@api/portal.api'; +import Duration from '@helpers/enums/duration'; +import grafanaHelper from '@helpers/grafana-helper'; +import { PortalUser } from '@helpers/types/portal-user.class'; +import { api } from '@api/api'; +import { portalHelper } from '@helpers/portal-helper'; + +test.describe('Spec file for connecting PMM to the portal', async () => { + let pmmVersion: number; + let firstAdmin: PortalUser; + let secondAdmin: PortalUser; + let technicalUser: PortalUser; + + test.beforeAll(async () => { + pmmVersion = (await api.pmm.serverV1.getPmmVersion()).minor; + [firstAdmin, secondAdmin, technicalUser] = portalHelper.loadUsersFromFile(); + }); + + test.beforeEach(async ({ page }) => { + await apiHelper.confirmTour(page); + await page.goto('/'); + }); + + test( + 'PMM-T809 PMM-T398 Verify Percona Platform elements on PMM Settings' + + ' Page @portal @pre-pmm-portal-upgrade', + async ({ page, perconaPlatformPage }) => { + test.skip(pmmVersion < 27, 'This test is for PMM version 2.27.0 and higher'); + + await test.step('1. Open Percona Platform tab in PMM Settings', async () => { + await grafanaHelper.authorize(page); + await page.goto(perconaPlatformPage.perconaPlatformURL); + await expect(perconaPlatformPage.perconaPlatformContainer).toBeVisible(); + + if (pmmVersion >= 35) { + await expect(perconaPlatformPage.elements.header_2_35).toBeVisible(); + } else { + // TODO: find out what works best .waitFor of expect + await page.getByText(perconaPlatformPage.labels.header).waitFor({ + state: 'visible', + }); + } + }); + + await test.step('2. Verify all required element are displayed.', async () => { + if (pmmVersion >= 35) { + await expect(perconaPlatformPage.elements.pmmServerIdHeader).toHaveText(perconaPlatformPage.labels.pmmServerId_35); + } else { + await expect(perconaPlatformPage.elements.pmmServerIdHeader).toHaveText(perconaPlatformPage.labels.pmmServerId); + } + + await expect(perconaPlatformPage.elements.pmmServerNameHeader).toHaveText(perconaPlatformPage.labels.pmmServerName); + await expect(perconaPlatformPage.elements.accessTokenHeader).toHaveText(perconaPlatformPage.labels.accessToken); + if (pmmVersion >= 35) { + await expect(perconaPlatformPage.buttons.createPerconaAccount).toHaveAttribute('href', perconaPlatformPage.links.portalLogin); + await expect(perconaPlatformPage.buttons.connect).toHaveText(perconaPlatformPage.labels.validateConnection); + } else { + await expect(perconaPlatformPage.buttons.connect).toHaveText(perconaPlatformPage.labels.connect); + } + + if (pmmVersion >= 35) { + await expect(perconaPlatformPage.buttons.getToken35).toHaveAttribute('href', perconaPlatformPage.links.portalProfile); + } else if (pmmVersion > 29 && pmmVersion < 35) { + await expect(perconaPlatformPage.buttons.getToken).toHaveAttribute('href', perconaPlatformPage.links.portalProfile); + } else { + await expect(perconaPlatformPage.buttons.getToken).toHaveAttribute('href', perconaPlatformPage.links.platformProfile); + } + }); + + await test.step('3. Verify that pmm server name and access token are required.', async () => { + await perconaPlatformPage.fields.pmmServerName.focus(); + await perconaPlatformPage.fields.accessToken.focus(); + await perconaPlatformPage.buttons.connect.click({ + force: true, + }); + await expect(perconaPlatformPage.elements.pmmServerNameError).toHaveText(perconaPlatformPage.labels.requiredField); + await expect(perconaPlatformPage.elements.accessTokenError).toHaveText(perconaPlatformPage.labels.requiredField); + }); + + await test.step('4. Verify user can connect to the portal only when server name and access token are valid.', async () => { + await perconaPlatformPage.fields.pmmServerName.type('Some Name'); + await perconaPlatformPage.fields.accessToken.type('Some Token'); + await expect(perconaPlatformPage.buttons.connect).toBeEnabled(); + }); + }, + ); + + test( + 'PMM-T1224 Verify user is notified about using old PMM version while trying to connect to Portal' + + ' @portal @pre-pmm-portal-upgrade @post-pmm-portal-upgrade', + async ({ page, perconaPlatformPage }) => { + test.skip(pmmVersion > 26, 'This test is for PMM version 2.26.0 and lower'); + + await grafanaHelper.authorize(page); + await page.goto(perconaPlatformPage.perconaPlatformURL); + await perconaPlatformPage.fields.pmmServerName.type(`Test Server ${Date.now()}`); + await perconaPlatformPage.fields.email.type(firstAdmin.email); + await perconaPlatformPage.fields.password.type(firstAdmin.password); + await perconaPlatformPage.buttons.connect.click(); + await perconaPlatformPage.toast.checkToastMessage(perconaPlatformPage.messages.oldPmmVersionError); + }, + ); + + test( + 'PMM-T1097 Verify PMM server is connected to Portal' + + ' @not-ui-pipeline @portal @pre-pmm-portal-upgrade', + async ({ page, perconaPlatformPage }) => { + test.skip(pmmVersion < 27, 'This test is for PMM version 2.27.0 and higher'); + + await test.step('1. Open Percona Platform tab in PMM Settings', async () => { + await grafanaHelper.authorize(page); + await page.goto(perconaPlatformPage.perconaPlatformURL); + await perconaPlatformPage.perconaPlatformContainer.waitFor({ + state: 'visible', + }); + }); + + await test.step('2. Connect PMM to the Portal', async () => { + const adminToken = await portalApi.getUserAccessToken(firstAdmin.email, firstAdmin.password); + + // pmm address is not set automatically in older pmms. + await perconaPlatformPage.connectToPortal(adminToken, `Test Server ${Date.now()}`, true); + }); + }, + ); + + test( + 'PMM-T1098 Verify All org users can login in connected PMM server' + + ' @not-ui-pipeline @portal @pre-pmm-portal-upgrade @post-pmm-portal-upgrade', + async ({ + page, loginPage, homeDashboardPage, + baseURL, + context, + }) => { + test.skip(pmmVersion < 27, 'This test is for PMM version 2.27.0 and higher'); + + await test.step('1. Login as admin user that created the org.', async () => { + await loginPage.oktaLogin(firstAdmin.email, firstAdmin.password); + await homeDashboardPage.pmmUpgrade.containers.upgradeContainer.waitFor({ + state: 'visible', timeout: Duration.OneMinute, + }); + await expect(page).toHaveURL(`${baseURL}/${loginPage.landingUrl}`); + await context.clearCookies(); + await page.reload(); + }); + + await test.step('1. Login as admin user that was invited to the org.', async () => { + await loginPage.oktaLogin(secondAdmin.email, secondAdmin.password); + await homeDashboardPage.pmmUpgrade.containers.upgradeContainer.waitFor({ + state: 'visible', timeout: Duration.OneMinute, + }); + await expect(page).toHaveURL(`${baseURL}/${loginPage.landingUrl}`); + await context.clearCookies(); + await page.reload(); + }); + + await test.step('1. Login as technical user that was invited to the org.', async () => { + await loginPage.oktaLogin(technicalUser.email, technicalUser.password); + await homeDashboardPage.pmmUpgrade.containers.upgradeContainer.waitFor({ + state: 'visible', timeout: Duration.OneMinute, + }); + await expect(page).toHaveURL(`${baseURL}/${loginPage.landingUrl}`); + await context.clearCookies(); + await page.reload(); + }); + }, + ); +}); diff --git a/playwright-tests/tests/portal/pmmPortalUpgrade.spec.ts b/playwright-tests/tests/portal/pmmPortalUpgrade.spec.ts index ce720288d..bc0f2adf1 100644 --- a/playwright-tests/tests/portal/pmmPortalUpgrade.spec.ts +++ b/playwright-tests/tests/portal/pmmPortalUpgrade.spec.ts @@ -1,8 +1,8 @@ import { test } from '@playwright/test'; -import { apiHelper } from '@api/helpers/apiHelper'; -import Duration from '@helpers/enums/Duration'; -import HomeDashboard from '@pages/HomeDashboard.page'; -import grafanaHelper from '@helpers/grafanaHelper'; +import { apiHelper } from '@api/helpers/api-helper'; +import Duration from '@helpers/enums/duration'; +import HomeDashboardPage from '@pages/home-dashboard.page'; +import grafanaHelper from '@helpers/grafana-helper'; import { api } from '@api/api'; test.describe('Spec file for PMM connected the portal', async () => { @@ -24,7 +24,7 @@ test.describe('Spec file for PMM connected the portal', async () => { test('Verify user is able to Upgrade PMM version @not-ui-pipeline @pmm-portal-upgrade', async ({ page }) => { test.setTimeout(Duration.TwentyMinutes); - const homeDashboard = new HomeDashboard(page); + const homeDashboard = new HomeDashboardPage(page); await grafanaHelper.authorize(page); await homeDashboard.pmmUpgrade.elements.currentVersion.waitFor({ diff --git a/playwright-tests/tests/portal/postPmmConnect.spec.ts b/playwright-tests/tests/portal/postPmmConnect.spec.ts index 2309304e7..8904eb5a4 100644 --- a/playwright-tests/tests/portal/postPmmConnect.spec.ts +++ b/playwright-tests/tests/portal/postPmmConnect.spec.ts @@ -1,22 +1,14 @@ -import { expect, test } from '@playwright/test'; -import { apiHelper } from '@api/helpers/apiHelper'; -import { PortalUser } from '@helpers/types/PortalUser'; -import { fileHelper } from '@helpers/fileHelper'; -import { SignInPage } from '@pages/SignIn.page'; -import HomeDashboard from '@pages/HomeDashboard.page'; -import TicketsPage from '@pages/platformPages/Tickets.page'; -import Duration from '@helpers/enums/Duration'; -import EntitlementsPage from '@pages/platformPages/Entitlements.page'; -import EnvironmentOverview from '@pages/platformPages/EnvironmentOverview.page'; -import grafanaHelper from '@helpers/grafanaHelper'; -import PerconaPlatform from '@pages/pmmSettings/PerconaPlatform.page'; +import { expect, test } from '@helpers/test-helper'; +import apiHelper from '@api/helpers/api-helper'; +import { PortalUser } from '@helpers/types/portal-user.class'; +import { fileHelper } from '@helpers/file-helper'; +import Duration from '@helpers/enums/duration'; +import grafanaHelper from '@helpers/grafana-helper'; import { api } from '@api/api'; -import { portalHelper } from '@helpers/portalHelper'; -import { PortalUserRoles } from '@helpers/enums/portalUserRoles'; +import { portalHelper } from '@helpers/portal-helper'; test.describe('Spec file for PMM connected the portal', async () => { test.skip(); - test.describe.configure({ retries: 0 }); let firstAdmin: PortalUser; let secondAdmin: PortalUser; let technicalUser: PortalUser; @@ -35,7 +27,8 @@ test.describe('Spec file for PMM connected the portal', async () => { await page.goto(''); }); - test('Verify user roles are untouched after PMM server upgrade @not-ui-pipeline @portal @post-pmm-portal-upgrade', async () => { + test('Verify user roles are untouched after PMM server upgrade' + + ' @not-ui-pipeline @portal @post-pmm-portal-upgrade', async () => { const users = await api.grafana.listOrgUsers(); const foundAdmin1User = users.find((user: any) => user.email === firstAdmin.email); const foundAdmin2User = users.find((user: any) => user.email === secondAdmin.email); @@ -46,24 +39,20 @@ test.describe('Spec file for PMM connected the portal', async () => { expect(foundTechnicalUser.role).toEqual('Viewer'); }); - test.skip('PMM-T1149 PMM-T1132 Verify PMM user logged in using SSO and member of SN account is able to see tickets @not-ui-pipeline @portal @post-pmm-portal-upgrade', async ({ - page, - context, + test.skip('PMM-T1149 PMM-T1132 Verify PMM user logged in using SSO and member of SN account is able to see tickets' + + ' @not-ui-pipeline @portal @post-pmm-portal-upgrade', async ({ + page, loginPage, homeDashboardPage, ticketsPage, context, }) => { - const signInPage = new SignInPage(page); - const homeDashboard = new HomeDashboard(page); - const ticketsPage = new TicketsPage(page); - if (pmmVersion > 27) { await test.step('1. Login to he connected pmm with SSO', async () => { - await signInPage.oktaLogin(firstAdmin.email, firstAdmin.password); - await homeDashboard.pmmUpgrade.elements.currentVersion.waitFor({ + await loginPage.oktaLogin(firstAdmin.email, firstAdmin.password); + await homeDashboardPage.pmmUpgrade.elements.currentVersion.waitFor({ state: 'visible', timeout: Duration.ThreeMinutes, }); }); await test.step('2. Verify that there is a side menu for organizational tickets', async () => { - await homeDashboard.sideMenu.elements.tickets.click(); + await homeDashboardPage.sideMenu.elements.tickets.click(); }); await test.step('3. Verify user can see tickets for his org.', async () => { @@ -95,21 +84,20 @@ test.describe('Spec file for PMM connected the portal', async () => { } }); - test.skip('PMM-T1152 Verify user logged in using SSO and is a member of SN account is able to see Entitlements @not-ui-pipeline @portal @post-pmm-portal-upgrade', async ({ page }) => { - const signInPage = new SignInPage(page); - const homeDashboard = new HomeDashboard(page); - const entitlementsPage = new EntitlementsPage(page); - + test.skip('PMM-T1152 Verify user logged in using SSO and is a member of SN account is able to see Entitlements' + + ' @not-ui-pipeline @portal @post-pmm-portal-upgrade', async ({ + page, loginPage, homeDashboardPage, entitlementsPage, + }) => { if (pmmVersion > 27) { await test.step('1. Login to he connected pmm with SSO', async () => { - await signInPage.oktaLogin(firstAdmin.email, firstAdmin.password); - await homeDashboard.pmmUpgrade.elements.currentVersion.waitFor({ + await loginPage.oktaLogin(firstAdmin.email, firstAdmin.password); + await homeDashboardPage.pmmUpgrade.elements.currentVersion.waitFor({ state: 'visible', timeout: Duration.ThreeMinutes, }); }); await test.step('2. Verify that there is a side menu for Entitlements', async () => { - await homeDashboard.sideMenu.elements.entitlements.click(); + await homeDashboardPage.sideMenu.elements.entitlements.click(); }); await test.step('3. Verify user can see entitlements for his org.', async () => { @@ -132,23 +120,20 @@ test.describe('Spec file for PMM connected the portal', async () => { } }); - test('PMM-T1168 PMM-T1222 Verify user can see the contacts from Percona @not-ui-pipeline @portal @post-pmm-portal-upgrade', async ({ - page, - context, + test.skip('PMM-T1168 PMM-T1222 Verify user can see the contacts from Percona' + + ' @not-ui-pipeline @portal @post-pmm-portal-upgrade', async ({ + page, loginPage, homeDashboardPage, environmentOverviewPage, context, }) => { await context.grantPermissions(['clipboard-write', 'clipboard-read']); - const homeDashboard = new HomeDashboard(page); - const signInPage = new SignInPage(page); - const environmentOverviewPage = new EnvironmentOverview(page); const userToken = await api.portal.getUserAccessToken(firstAdmin.email, firstAdmin.password); const contactsEmail = (await api.portal.getOrgDetails(userToken, firstAdmin.org!.id)).contacts.customer_success.email; if (pmmVersion >= 29) { - await signInPage.oktaLogin(firstAdmin.email, firstAdmin.password); - await homeDashboard.pmmUpgrade.elements.currentVersion.waitFor({ + await loginPage.oktaLogin(firstAdmin.email, firstAdmin.password); + await homeDashboardPage.pmmUpgrade.elements.currentVersion.waitFor({ state: 'visible', timeout: Duration.ThreeMinutes, }); - await homeDashboard.sideMenu.elements.environmentOverview.click(); + await homeDashboardPage.sideMenu.elements.environmentOverview.click(); await environmentOverviewPage.elements.contactsHeader.waitFor({ state: 'visible', }); @@ -171,20 +156,20 @@ test.describe('Spec file for PMM connected the portal', async () => { } }); - test.skip('PMM-T1147 Verify PMM user that is not logged in with SSO can NOT see Tickets for organization @not-ui-pipeline @portal @post-pmm-portal-upgrade', async ({ page }) => { - const homeDashboard = new HomeDashboard(page); - const ticketsPage = new TicketsPage(page); - + test.skip('PMM-T1147 Verify PMM user that is not logged in with SSO can NOT see Tickets for organization' + + ' @not-ui-pipeline @portal @post-pmm-portal-upgrade', async ({ + page, homeDashboardPage, ticketsPage, + }) => { if (pmmVersion > 27) { await test.step('1. Login to he connected pmm with SSO', async () => { await grafanaHelper.authorize(page); - await homeDashboard.pmmUpgrade.elements.currentVersion.waitFor({ + await homeDashboardPage.pmmUpgrade.elements.currentVersion.waitFor({ state: 'visible', timeout: Duration.ThreeMinutes, }); }); await test.step('2. Verify that there is NO side menu for organizational tickets', async () => { - await homeDashboard.sideMenu.elements.tickets.waitFor({ + await homeDashboardPage.sideMenu.elements.tickets.waitFor({ state: 'detached', }); }); @@ -205,20 +190,20 @@ test.describe('Spec file for PMM connected the portal', async () => { } }); - test.skip('PMM-T1154 Verify PMM user that is not logged in with SSO can NOT see Entitlements for organization @not-ui-pipeline @portal @post-pmm-portal-upgrade', async ({ page }) => { - const homeDashboard = new HomeDashboard(page); - const entitlementsPage = new EntitlementsPage(page); - + test.skip('PMM-T1154 Verify PMM user that is not logged in with SSO can NOT see Entitlements for organization' + + ' @not-ui-pipeline @portal @post-pmm-portal-upgrade', async ({ + page, homeDashboardPage, entitlementsPage, + }) => { if (pmmVersion > 27) { await test.step('1. Login to the connected pmm with local account', async () => { await grafanaHelper.authorize(page); - await homeDashboard.pmmUpgrade.elements.currentVersion.waitFor({ + await homeDashboardPage.pmmUpgrade.elements.currentVersion.waitFor({ state: 'visible', timeout: Duration.ThreeMinutes, }); }); await test.step('2. Verify that there is NO side menu for organizational Entitlements', async () => { - await homeDashboard.sideMenu.elements.entitlements.waitFor({ + await homeDashboardPage.sideMenu.elements.entitlements.waitFor({ state: 'detached', }); }); @@ -239,20 +224,20 @@ test.describe('Spec file for PMM connected the portal', async () => { } }); - test.skip('PMM-T1170 Verify PMM user that is not logged in with SSO can NOT see Contacts for organization @not-ui-pipeline @portal @post-pmm-portal-upgrade', async ({ page }) => { - const homeDashboard = new HomeDashboard(page); - const environmentOverview = new EnvironmentOverview(page); - + test.skip('PMM-T1170 Verify PMM user that is not logged in with SSO can NOT see Contacts for organization' + + ' @not-ui-pipeline @portal @post-pmm-portal-upgrade', async ({ + page, homeDashboardPage, environmentOverviewPage, + }) => { if (pmmVersion > 27) { await test.step('1. Login to the connected pmm with local account', async () => { await grafanaHelper.authorize(page); - await homeDashboard.pmmUpgrade.elements.currentVersion.waitFor({ + await homeDashboardPage.pmmUpgrade.elements.currentVersion.waitFor({ state: 'visible', timeout: Duration.ThreeMinutes, }); }); await test.step('1. Login to the connected pmm with local account', async () => { - await page.goto(environmentOverview.environmentOverviewUrl); - await expect(environmentOverview.elements.notPlatformUser).toHaveText(environmentOverview.messages.loginWithPercona); + await page.goto(environmentOverviewPage.environmentOverviewUrl); + await expect(environmentOverviewPage.elements.notPlatformUser).toHaveText(environmentOverviewPage.messages.loginWithPercona); }); } else { test.info().annotations.push({ @@ -262,21 +247,21 @@ test.describe('Spec file for PMM connected the portal', async () => { } }); - test.skip('PMM-T1148 Verify PMM user logged in using SSO and member of organization in Portal BUT not a SN account is NOT able to see Tickets @not-ui-pipeline @portal @post-pmm-portal-upgrade', async ({ page }) => { - const signInPage = new SignInPage(page); - const homeDashboard = new HomeDashboard(page); - const ticketsPage = new TicketsPage(page); - + test.skip('PMM-T1148 Verify PMM user logged in using SSO and member of organization in Portal' + + ' BUT not a SN account is NOT able to see Tickets' + + ' @not-ui-pipeline @portal @post-pmm-portal-upgrade', async ({ + loginPage, homeDashboardPage, ticketsPage, + }) => { if (pmmVersion > 27) { await test.step('1. Login to he connected pmm with SSO', async () => { - await signInPage.oktaLogin(freeUser.email, freeUser.password); - await homeDashboard.pmmUpgrade.elements.currentVersion.waitFor({ + await loginPage.oktaLogin(freeUser.email, freeUser.password); + await homeDashboardPage.pmmUpgrade.elements.currentVersion.waitFor({ state: 'visible', timeout: Duration.ThreeMinutes, }); }); await test.step('2. Verify that there is a side menu for organizational tickets', async () => { - await homeDashboard.sideMenu.elements.tickets.click(); + await homeDashboardPage.sideMenu.elements.tickets.click(); }); await test.step('3. Verify user can NOT see tickets for his org.', async () => { @@ -290,24 +275,20 @@ test.describe('Spec file for PMM connected the portal', async () => { } }); - test.skip('PMM-T1153 Verify user logged in using SSO and is not a member of SN account is NOT able to see Entitlements @not-ui-pipeline @portal @post-pmm-portal-upgrade', async ({ page }) => { - const signInPage = new SignInPage(page); - const homeDashboard = new HomeDashboard(page); - const ticketsPage = new TicketsPage(page); - const entitlementsPage = new EntitlementsPage(page); - + test.skip('PMM-T1153 Verify user logged in using SSO and is not a member of SN account is NOT able to see Entitlements' + + ' @not-ui-pipeline @portal @post-pmm-portal-upgrade', async ({ + loginPage, homeDashboardPage, ticketsPage, entitlementsPage, + }) => { if (pmmVersion > 27) { await test.step('1. Login to he connected pmm with SSO', async () => { - await signInPage.oktaLogin(freeUser.email, freeUser.password); - await homeDashboard.pmmUpgrade.elements.currentVersion.waitFor({ + await loginPage.oktaLogin(freeUser.email, freeUser.password); + await homeDashboardPage.pmmUpgrade.elements.currentVersion.waitFor({ state: 'visible', timeout: Duration.ThreeMinutes, }); }); - await test.step('2. Verify that there is a side menu for organizational Entitlements', async () => { - await homeDashboard.sideMenu.elements.entitlements.click(); + await homeDashboardPage.sideMenu.elements.entitlements.click(); }); - await test.step('3. Verify user can NOT see Entitlements for his org.', async () => { await expect(ticketsPage.elements.noData).toHaveText(entitlementsPage.messages.noEntitlements); }); @@ -319,39 +300,38 @@ test.describe('Spec file for PMM connected the portal', async () => { } }); - test('PMM-T1204 PMM-T1112 Verify user can disconnect pmm from portal success flow @portal @not-ui-pipeline @post-pmm-portal-upgrade', async ({ page }) => { - const signInPage = new SignInPage(page); - const homeDashboard = new HomeDashboard(page); - const platformPage = new PerconaPlatform(page); - + test('PMM-T1204 PMM-T1112 Verify user can disconnect pmm from portal success flow' + + ' @portal @not-ui-pipeline @post-pmm-portal-upgrade', async ({ + page, loginPage, homeDashboardPage, perconaPlatformPage, + }) => { if (pmmVersion > 27) { - await signInPage.oktaLogin(firstAdmin.email, firstAdmin.password); - await homeDashboard.pmmUpgrade.elements.currentVersion.waitFor({ + await loginPage.oktaLogin(firstAdmin.email, firstAdmin.password); + await homeDashboardPage.pmmUpgrade.elements.currentVersion.waitFor({ state: 'visible', timeout: Duration.ThreeMinutes, }); - await page.goto(platformPage.perconaPlatformURL); - await platformPage.connectedContainer.waitFor({ + await page.goto(perconaPlatformPage.perconaPlatformURL); + await perconaPlatformPage.connectedContainer.waitFor({ state: 'visible', }); - await platformPage.buttons.disconnect.click(); + await perconaPlatformPage.buttons.disconnect.click(); if (pmmVersion >= 28) { - await expect(platformPage.elements.modalMessage).toHaveText(platformPage.messages.disconnectWarning); - await platformPage.buttons.confirmDisconnect.click(); + await expect(perconaPlatformPage.elements.modalMessage).toHaveText(perconaPlatformPage.messages.disconnectWarning); + await perconaPlatformPage.buttons.confirmDisconnect.click(); await page.locator('//input[@name="user"]').waitFor({ state: 'visible', }); } else { - await platformPage.toast.checkToastMessage(platformPage.messages.pmmDisconnectedFromPortal); + await perconaPlatformPage.toast.checkToastMessage(perconaPlatformPage.messages.pmmDisconnectedFromPortal); } await grafanaHelper.authorize(page); - await homeDashboard.pmmUpgrade.elements.currentVersion.waitFor({ + await homeDashboardPage.pmmUpgrade.elements.currentVersion.waitFor({ state: 'visible', timeout: Duration.ThreeMinutes, }); - await page.goto(platformPage.perconaPlatformURL); + await page.goto(perconaPlatformPage.perconaPlatformURL); const adminToken = await api.portal.getUserAccessToken(firstAdmin.email, firstAdmin.password); - await platformPage.connectToPortal(adminToken, `Test Server ${Date.now()}`, true); + await perconaPlatformPage.connectToPortal(adminToken, `Test Server ${Date.now()}`, true); } else { test.info().annotations.push({ type: 'Old Version ', @@ -360,42 +340,43 @@ test.describe('Spec file for PMM connected the portal', async () => { } }); // Needs to be fixed in the future. - test.skip('PMM-T1264 Verify that pmm admin user can force disconnect pmm from the portal. @not-ui-pipeline @portal @post-pmm-portal-upgrade', async ({ page }) => { + test.skip('PMM-T1264 Verify that pmm admin user can force disconnect pmm from the portal' + + ' @not-ui-pipeline @portal @post-pmm-portal-upgrade', async ({ + page, perconaPlatformPage, + }) => { test.skip(pmmVersion < 29, 'This test is for PMM version 2.29.0 and higher'); - const platformPage = new PerconaPlatform(page); await test.step('1. Login into the pmm and navigate to the percona platform page.', async () => { await grafanaHelper.authorize(page); - await page.goto(platformPage.perconaPlatformURL); - await platformPage.connectedContainer.waitFor({ + await page.goto(perconaPlatformPage.perconaPlatformURL); + await perconaPlatformPage.connectedContainer.waitFor({ state: 'visible', }); }); await test.step('2. Force disconnect from the platform.', async () => { - await platformPage.buttons.disconnect.click(); - await expect(platformPage.elements.forceDisconnectModal).toHaveText(platformPage.messages.forceDisconnectWarning); - await expect(platformPage.elements.readMore).toHaveAttribute('href', platformPage.links.readMore); - await platformPage.buttons.confirmDisconnect.click(); + await perconaPlatformPage.buttons.disconnect.click(); + await expect(perconaPlatformPage.elements.forceDisconnectModal).toHaveText(perconaPlatformPage.messages.forceDisconnectWarning); + await expect(perconaPlatformPage.elements.readMore).toHaveAttribute('href', perconaPlatformPage.links.readMore); + await perconaPlatformPage.buttons.confirmDisconnect.click(); }); await test.step('3. Verify that force disconnect was successful.', async () => { - await platformPage.toast.checkToastMessage(platformPage.messages.disconnectedSuccess); - await platformPage.buttons.connect.waitFor({ + await perconaPlatformPage.toast.checkToastMessage(perconaPlatformPage.messages.disconnectedSuccess); + await perconaPlatformPage.buttons.connect.waitFor({ state: 'visible', }); }); }); - test('PMM-T1247 Verify user cannot access platform functionality when PMM is not connected to the portal. @not-ui-pipeline @portal @post-pmm-portal-upgrade', async ({ page }) => { - const environmentOverview = new EnvironmentOverview(page); - const entitlementsPage = new EntitlementsPage(page); - const ticketsPage = new TicketsPage(page); - + test.skip('PMM-T1247 Verify user cannot access platform functionality when PMM is not connected to the portal' + + ' @not-ui-pipeline @portal @post-pmm-portal-upgrade', async ({ + page, environmentOverviewPage, entitlementsPage, ticketsPage, + }) => { await grafanaHelper.authorize(page); - await page.goto(environmentOverview.environmentOverviewUrl); - await expect(environmentOverview.elements.notConnectedToPlatform).toHaveText( - environmentOverview.messages.notConnectedToThePortal, + await page.goto(environmentOverviewPage.environmentOverviewUrl); + await expect(environmentOverviewPage.elements.notConnectedToPlatform).toHaveText( + environmentOverviewPage.messages.notConnectedToThePortal, ); await page.goto(entitlementsPage.entitlementsUrl); @@ -405,7 +386,7 @@ test.describe('Spec file for PMM connected the portal', async () => { await expect(ticketsPage.elements.notConnectedToPlatform).toHaveText(ticketsPage.messages.notConnectedToThePortal); }); - test('After tests cleanup.', async () => { + test.skip('After tests cleanup.', async () => { const adminToken = await api.portal.getUserAccessToken(firstAdmin.email, firstAdmin.password); const org = await api.portal.getOrg(adminToken); diff --git a/playwright-tests/tests/portal/testUsers.setup.ts b/playwright-tests/tests/portal/testUsers.setup.ts index e3faa6223..257a20fe3 100644 --- a/playwright-tests/tests/portal/testUsers.setup.ts +++ b/playwright-tests/tests/portal/testUsers.setup.ts @@ -1,8 +1,8 @@ import { test as setup } from '@playwright/test'; import { api } from '@api/api'; -import { portalHelper } from '@helpers/portalHelper'; -import { fileHelper } from '@helpers/fileHelper'; -import { Constants } from '@helpers/Constants'; +import { portalHelper } from '@helpers/portal-helper'; +import { fileHelper } from '@helpers/file-helper'; +import constants from '@helpers/constants'; /** * Extension point: before Portal tests. @@ -15,15 +15,15 @@ setup('Setup Portal tests', async ({ baseURL }) => { }); }); await setup.step('Remove old credentials file if it\'s there', async () => { - if (fileHelper.fileExists(Constants.portal.credentialsFile)) { + if (fileHelper.fileExists(constants.portal.credentialsFile)) { console.log('Found file with Portal test users! Removing...'); - await fileHelper.removeFile(Constants.portal.credentialsFile); + await fileHelper.removeFile(constants.portal.credentialsFile); } }); await setup.step('Generate new users and save to file', async () => { const [firstAdmin, secondAdmin, technicalUser, freeUser] = await portalHelper.createNewUsers(); fileHelper.writeToFile( - Constants.portal.credentialsFile, + constants.portal.credentialsFile, JSON.stringify([firstAdmin, secondAdmin, technicalUser, freeUser]), ); }); diff --git a/playwright-tests/tests/rbac/rbac.spec.ts b/playwright-tests/tests/rbac/rbac.spec.ts index 8ae05d635..3cb1aaafb 100644 --- a/playwright-tests/tests/rbac/rbac.spec.ts +++ b/playwright-tests/tests/rbac/rbac.spec.ts @@ -1,27 +1,35 @@ import { expect, test } from '@playwright/test'; -import { apiHelper } from '@api/helpers/apiHelper'; -import HomeDashboard from '@tests/pages/HomeDashboard.page'; -import grafanaHelper from '@helpers/grafanaHelper'; -import { RbacPage } from '@tests/tests/configuration/pages/Rbac.page'; -import { CreateRolePage } from '@tests/tests/configuration/pages/CreateRole.page'; -import { NewUserPage } from '@tests/pages/serverAdmin/NewUser.page'; -import { UsersConfigurationPage } from '@tests/tests/configuration/pages/UsersConfiguration.page'; -import { MySqlDashboard } from '@tests/pages/dashboards/mysql/MySqlDashboard.page'; -import NodesOverviewDashboard from '@tests/pages/dashboards/nodes/NodesOverviewDashboard.page'; -import Duration from '@helpers/enums/Duration'; -import PostgresqlInstancesOverviewDashboard from '@tests/pages/dashboards/postgresql/PostgresqlInstancesOverview.page'; -import AdvancedSettings from '@tests/pages/pmmSettings/AdvancedSettings.page'; +import apiHelper from '@api/helpers/api-helper'; +import HomeDashboardPage from '@pages/home-dashboard.page'; +import grafanaHelper from '@helpers/grafana-helper'; +import { RbacPage } from '@tests/configuration/pages/rbac.page'; +import { CreateRolePage } from '@tests/configuration/pages/create-role.page'; +import { NewUserPage } from '@pages/serverAdmin/NewUser.page'; +import { UsersConfigurationPage } from '@tests/configuration/pages/users-configuration.page'; +import { MySqlDashboard } from '@pages/dashboards/mysql/mysql-dashboard.page'; +import NodesOverviewDashboard from '@pages/dashboards/nodes/nodes-overview-dashboard.page'; +import Duration from '@helpers/enums/duration'; +import PostgresqlInstancesOverviewDashboard from '@pages/dashboards/postgresql/postgresql-iInstances-overview.page'; +import AdvancedSettings from '@pages/pmm-settings/advanced-settings.page'; import { api } from '@api/api'; -import { ListRoles } from '@tests/api/management'; -import { PmmVersion } from '@helpers/types/PmmVersion'; -import * as console from 'console'; - -console.log(`${!!process.env.PMM_SERVER_START_VERSION}`); -let pmmVersion = process.env.PMM_SERVER_START_VERSION - ? new PmmVersion(process.env.PMM_SERVER_START_VERSION).minor - : null; +import { ListRoles } from '@api/management.api'; +import PmmVersion from '@helpers/types/pmm-version.class'; + +let pmmVersion: number; let roles: ListRoles | undefined; +/** + * Cp. Obvious: Lazy initialization. + */ +const getPmmVersion = async (): Promise => { + if (!pmmVersion) { + pmmVersion = process.env.PMM_SERVER_START_VERSION + ? new PmmVersion(process.env.PMM_SERVER_START_VERSION).minor + : (await api.pmm.serverV1.getPmmVersion()).minor; + } + return pmmVersion; +}; + /** * Cp. Obvious: Lazy initialization */ @@ -29,12 +37,12 @@ const getRolesObj = async (): Promise => { if (!roles) { roles = await api.pmm.managementV1.listRoles(); } - return roles; }; test.describe('Spec file for Access Control (RBAC)', async () => { - test.skip(!!pmmVersion && pmmVersion < 35, 'Test is for PMM version 2.35.0+'); + // test.skip(await getPmmVersion() < 35, 'Test is for PMM version 2.35.0+'); + // test.skip(() => getPmmVersion() < 35); const newUser = { username: 'testUserRBAC', email: 'testUserRBAC@localhost', name: 'Test User', password: 'password', }; @@ -56,12 +64,12 @@ test.describe('Spec file for Access Control (RBAC)', async () => { }); test('PMM-T1573 Verify Access Roles tab on Configuration page @rbac @rbac-pre-upgrade', async ({ page }) => { - test.skip(pmmVersion! < 35, 'Test is for versions 2.35.0+'); + test.skip(await getPmmVersion() < 35, 'Test is for versions 2.35.0+'); test.info().annotations.push({ type: 'Also Covers', description: 'PMM-T1579 Verify docker variable to enable Access control (RBAC)', }); - const homeDashboard = new HomeDashboard(page); + const homeDashboard = new HomeDashboardPage(page); const rbacPage = new RbacPage(page); await test.step('1. Click on Configuration on the left menu and then select Access roles link', async () => { @@ -83,7 +91,7 @@ test.describe('Spec file for Access Control (RBAC)', async () => { }); test('PMM-T1580 Verify creating Access Role @rbac @rbac-pre-upgrade @rbac-post-upgrade', async ({ page }) => { - test.skip(pmmVersion! < 35, 'Test is for versions 2.35.0+'); + test.skip(await getPmmVersion() < 35, 'Test is for versions 2.35.0+'); test.info().annotations.push({ type: 'Also Covers', description: 'PMM-T1581 Verify assigning default role on Access roles page.', @@ -122,7 +130,7 @@ test.describe('Spec file for Access Control (RBAC)', async () => { }); test('PMM-T1584 Verify assigning Access role to user @rbac @rbac-pre-upgrade @rbac-post-upgrade', async ({ page }) => { - test.skip(pmmVersion! < 35, 'Test is for versions 2.35.0+'); + test.skip(await getPmmVersion() < 35, 'Test is for versions 2.35.0+'); test.skip((await getRolesObj())?.roles.length !== 1, 'For updating from version without RBAC (<35)'); const rbacPage = new RbacPage(page); const createRolePage = new CreateRolePage(page); @@ -168,7 +176,7 @@ test.describe('Spec file for Access Control (RBAC)', async () => { }); test('PMM-T1599 Verify assigned role after upgrade @rbac @rbac-post-upgrade', async ({ page }) => { - test.skip(pmmVersion! < 35, 'Test is for versions 2.35.0+'); + test.skip(await getPmmVersion() < 35, 'Test is for versions 2.35.0+'); const usersConfigurationPage = new UsersConfigurationPage(page); const postgresqlInstancesOverviewDashboard = new PostgresqlInstancesOverviewDashboard(page); @@ -186,7 +194,7 @@ test.describe('Spec file for Access Control (RBAC)', async () => { }); test('PMM-T1585 Verify deleting Access role @rbac @rbac-post-upgrade', async ({ page }) => { - test.skip(pmmVersion! < 35, 'Test is for versions 2.35.0+'); + test.skip(await getPmmVersion() < 35, 'Test is for versions 2.35.0+'); test.info().annotations.push({ type: 'Also Covers', description: 'PMM-T1578 Verify there is ability to enable Access control on Settings page.', @@ -232,7 +240,7 @@ test.describe('Spec file for Access Control (RBAC)', async () => { }); test('PMM-T1652 Verify replacing the role while removing it @rbac @rbac-post-upgrade', async ({ page }) => { - test.skip(pmmVersion! < 35, 'Test is for versions 2.35.0+'); + test.skip(await getPmmVersion() < 35, 'Test is for versions 2.35.0+'); const rbacPage = new RbacPage(page); const createRolePage = new CreateRolePage(page); const newUserPage = new NewUserPage(page); @@ -286,7 +294,7 @@ test.describe('Spec file for Access Control (RBAC)', async () => { type: 'Also Covers', description: 'PMM-T1601 Verify Grafana Does not crash when filtering users from the admin page.', }); - test.skip(pmmVersion! < 36, 'Test is for versions 2.36.0+'); + test.skip(await getPmmVersion() < 36, 'Test is for versions 2.36.0+'); const rbacPage = new RbacPage(page); const createRolePage = new CreateRolePage(page); const newUserPage = new NewUserPage(page); @@ -350,9 +358,9 @@ test.describe('Spec file for Access Control (RBAC)', async () => { }); test('PMM-T1629 Verify re-enabling of the Access Control @rbac @rbac-post-upgrade', async ({ page }) => { - test.skip(pmmVersion! < 35, 'Test is for versions 2.35.0+'); + test.skip(await getPmmVersion() < 35, 'Test is for versions 2.35.0+'); const advancedSettings = new AdvancedSettings(page); - const homeDashboard = new HomeDashboard(page); + const homeDashboard = new HomeDashboardPage(page); const rbacPage = new RbacPage(page); await test.step('1.Navigate to the advanced settings and disable Access Control.', async () => { diff --git a/playwright-tests/tests/upgrade/upgradePmmViaUi.spec.ts b/playwright-tests/tests/upgrade/upgradePmmViaUi.spec.ts index f2c6b0143..139d80e67 100644 --- a/playwright-tests/tests/upgrade/upgradePmmViaUi.spec.ts +++ b/playwright-tests/tests/upgrade/upgradePmmViaUi.spec.ts @@ -1,7 +1,6 @@ -import { test } from '@playwright/test'; -import { apiHelper } from '@api/helpers/apiHelper'; -import grafanaHelper from '@helpers/grafanaHelper'; -import HomeDashboard from '@pages/HomeDashboard.page'; +import { test } from '@helpers/test-helper'; +import apiHelper from '@api/helpers/api-helper'; +import grafanaHelper from '@helpers/grafana-helper'; test.describe('Common Upgrade PMM tests', async () => { test.describe.configure({ retries: 0 }); @@ -12,14 +11,11 @@ test.describe('Common Upgrade PMM tests', async () => { await page.goto(''); }); - test('PMM-T288 Verify user can see Update widget before upgrade [critical] @pmm-upgrade', async ({ page }) => { - const homeDashboard = new HomeDashboard(page); - await homeDashboard.pmmUpgrade.verifyUpgradeWidget(); + test('PMM-T288 Verify user can see Update widget before upgrade [critical] @pmm-upgrade', async ({ homeDashboardPage }) => { + await homeDashboardPage.pmmUpgrade.verifyUpgradeWidget(); }); - test('PMM-T3 Verify user is able to Upgrade PMM version [blocker] @pmm-upgrade', async ({ page }) => { - const homeDashboard = new HomeDashboard(page); - - await homeDashboard.upgradePMM(); + test('PMM-T3 Verify user is able to Upgrade PMM version [blocker] @pmm-upgrade', async ({ homeDashboardPage }) => { + await homeDashboardPage.upgradePMM(); }); }); diff --git a/playwright-tests/tsconfig.json b/playwright-tests/tsconfig.json index dc4157d2a..8ab5dd3d6 100644 --- a/playwright-tests/tsconfig.json +++ b/playwright-tests/tsconfig.json @@ -15,12 +15,12 @@ "dom" ], "paths": { - "@tests/*": ["./*"], + "@tests/*": ["tests/*"], "@pages/*": ["pages/*"], "@api/*": ["api/*"], "@root/*": ["./*"], "@helpers/*": ["helpers/*"], - "@components/*": ["components/*"] + "@components/*": ["pages/page-components/*"] }, "noEmit": true, "noFallthroughCasesInSwitch": true,