diff --git a/config/scenarioUrls.json b/config/scenarioUrls.json index da17a91..2f973f2 100644 --- a/config/scenarioUrls.json +++ b/config/scenarioUrls.json @@ -54,5 +54,19 @@ "path": "", "mobile": true } + }, + "@vr": { + "delayJs68Live": { + "path": "delayjs_68_live_template" + }, + "lcp6647Live": { + "path": "lcp_6647_live" + }, + "lcpLive4Template": { + "path": "lcp_live_4_template" + }, + "lcpLiveTestSpan": { + "path": "lcp_live_test_span" + } } } \ No newline at end of file diff --git a/package.json b/package.json index 514171f..e003a15 100755 --- a/package.json +++ b/package.json @@ -10,11 +10,11 @@ "scripts": { "lint": "eslint . --ext .ts", "lint:fix": "eslint . --ext .ts --fix", - "test:e2e": "$npm_package_config_testCommand ; npm run push-report --tag=$npm_config_tag", + "test:e2e": "$npm_package_config_testCommand --tags \"not @vr\" ; npm run push-report --tag=$npm_config_tag", "test:smoke": "$npm_package_config_testCommand --tags @smoke ; npm run push-report --tag=$npm_config_tag", "test:local": "$npm_package_config_testCommand --tags @local", "test:online": "$npm_package_config_testCommand --tags @online", - "test:vr": "$npm_package_config_testCommand --tags @vr", + "test:vr": "$npm_package_config_testCommand --tags @vr $npm_config_wproption", "test:llcssbg": "$npm_package_config_testCommand --tags @llcssbg", "test:delayjs": "$npm_package_config_testCommand --tags @delayjs", "test:lcp": "$npm_package_config_testCommand --tags @lcp", diff --git a/src/common/custom-world.ts b/src/common/custom-world.ts index 27a8fc8..36d1445 100644 --- a/src/common/custom-world.ts +++ b/src/common/custom-world.ts @@ -28,6 +28,7 @@ import { Pickle } from '@cucumber/messages'; import { BrowserContext, Page } from '@playwright/test'; import { Sections } from './sections'; import { PageUtils } from '../../utils/page-utils'; +import type { Section } from "../../utils/types"; export interface ICustomWorld extends World { context?: BrowserContext; @@ -35,6 +36,8 @@ export interface ICustomWorld extends World { sections?: Sections; utils?: PageUtils; pickle?: Pickle; + wprSection?: Section; + wprOption?: string; } export class CustomWorld extends World implements ICustomWorld { diff --git a/src/features/visual-regression.feature b/src/features/visual-regression.feature index 425a2d8..5ea5fd7 100644 --- a/src/features/visual-regression.feature +++ b/src/features/visual-regression.feature @@ -1,6 +1,11 @@ -@vr +@vr @setup Feature: Visual Regression Test Scenario: Test any page for visual regression - When I create reference - Then I must not see any visual regression 'general' \ No newline at end of file + Given visual regression reference is generated + And I am logged in + And plugin is installed 'new_release' + And plugin is activated + And I go to 'wp-admin/options-general.php?page=wprocket#dashboard' + When I enable option + Then I must not see any visual regression in scenario urls \ No newline at end of file diff --git a/src/support/hooks.ts b/src/support/hooks.ts index ed14a55..09573de 100644 --- a/src/support/hooks.ts +++ b/src/support/hooks.ts @@ -23,6 +23,8 @@ import { deleteFolder, isWprRelatedError } from "../../utils/helpers"; import {WP_SSH_ROOT_DIR,} from "../../config/wp.config"; import { After, AfterAll, Before, BeforeAll, Status, setDefaultTimeout } from "@cucumber/cucumber"; import {rename, exists, rm, testSshConnection, installRemotePlugin, activatePlugin, uninstallPlugin, readFile} from "../../utils/commands"; +import type { Selectors } from "../../utils/types"; +import type { Section } from "../../utils/types"; // import {configurations, getWPDir} from "../../utils/configurations"; /** @@ -155,6 +157,35 @@ Before({tags: '@delaylcp'}, async function (this: ICustomWorld) { await activatePlugin('rocket-lcp-delay'); }); +/** + * Before each test scenario with the @vr tag, performs setup tasks. + */ +Before({tags: '@vr'}, async function (this: ICustomWorld) { + const option = process.env.npm_config_wproption; + + if(!option) { + throw new Error('Option label not correctly parsed. Check that the labels are defined') + } + + const elementKeys: string[] = []; + const elementToParentMap: Record = {}; + + // Loop through each top-level key + Object.entries(pluginSelectors as Selectors).forEach(([parentKey, { elements }]) => { + Object.keys(elements).forEach(elementKey => { + elementKeys.push(elementKey); + elementToParentMap[elementKey] = parentKey; + }); + }); + + if (!elementKeys.includes(option)) { + throw new Error('Value for option label is invalid. Refer to src/common/selectors'); + } + + this.wprSection = elementToParentMap[option] as Section; + this.wprOption = option; +}); + /** * After each test scenario, performs cleanup tasks and captures screenshots and videos in case of failure. */ diff --git a/src/support/steps/general.ts b/src/support/steps/general.ts index c45292a..725d6ff 100644 --- a/src/support/steps/general.ts +++ b/src/support/steps/general.ts @@ -16,13 +16,14 @@ import { ICustomWorld } from "../../common/custom-world"; import { Given, When, Then } from '@cucumber/cucumber'; import {WP_BASE_URL} from '../../../config/wp.config'; import scenarioUrls from "./../../../config/scenarioUrls.json"; -import { createReference, compareReference, isTagPresent, getScenarioTag, batchUpdateVRTestUrl } from "../../../utils/helpers"; +import { compareReference, isTagPresent, getScenarioTag, batchUpdateVRTestUrl } from "../../../utils/helpers"; import type { Section } from "../../../utils/types"; import { Page } from '@playwright/test'; import { deactivatePlugin, installRemotePlugin, } from "../../../utils/commands"; import backstop from 'backstopjs'; + /** * Executes the step to log in. */ @@ -145,6 +146,27 @@ Given('visual regression reference is generated', async function (this:ICustomWo process.env.scenario_tag = tag; }); +/** + * Clear wpr cache + */ +Given('clear wpr cache', async function (this: ICustomWorld) { + await this.utils.clearWPRCache(); +}); + +/** + * Executes the step to deactivate a specified WP plugin via CLI. + */ +Given('plugin {word} is deactivated', async function (plugin) { + await deactivatePlugin(plugin) +}); + +/** + * Executes the step to install a WP plugin from a remote url via CLI. + */ +Given('I install plugin {string}', async function (pluginUrl) { + await installRemotePlugin(pluginUrl) +}); + /** * Executes the step to log in. */ @@ -159,14 +181,6 @@ When('I go to {string}', async function (this: ICustomWorld, page) { await this.utils.visitPage(page); }); -/** - * Clear wpr cache - */ -Given('clear wpr cache', async function (this: ICustomWorld) { - await this.utils.clearWPRCache(); -}); - - /** * Executes the step to click on a specific button. */ @@ -216,17 +230,6 @@ When('I visit site url', async function (this: ICustomWorld) { await this.page.goto(WP_BASE_URL); }); -/** - * Executes the step to create a reference. - */ -When('I create reference', async function (this:ICustomWorld) { - if (process.env.npm_config_vrurl === undefined) { - return; - } - - await createReference(process.env.npm_config_vrurl); -}); - /** * Executes the step visit a page in mobile view. */ @@ -340,6 +343,22 @@ When('permalink structure is changed to {string}', async function (this: ICustom await this.utils.permalinkChanged(structure); }); +When('I enable option', async function (this: ICustomWorld) { + // If section does not exist and element is cacheLoggedUser, toggle the element in addons section. + if (!(await this.sections.doesSectionExist(this.wprSection))) { + if (this.wprOption === 'cacheLoggedUser') { + await this.sections.set('addons').visit(); + await this.sections.state(true).toggle(this.wprOption); + } + + return; + } + + await this.sections.set(this.wprSection).visit(); + await this.sections.state(true).toggle(this.wprOption); + await this.utils.saveSettings(); + +}); /** * Executes the step to assert the presence of specific text. */ @@ -361,7 +380,6 @@ Then('I must not see any error in debug.log', async function (this: ICustomWorld /** * Executes the step to clean up WP Rocket. */ - Then('clean up', async function (this: ICustomWorld) { await this.utils.cleanUp(); }); @@ -452,18 +470,4 @@ Then('page navigated to the new page {string}', async function (this: ICustomWor const url = `${WP_BASE_URL}/${path}`; const regex = new RegExp(url); await expect(this.page).toHaveURL(regex); -}); - -/** - * Executes the step to deactivate a specified WP plugin via CLI. - */ -Given('plugin {word} is deactivated', async function (plugin) { - await deactivatePlugin(plugin) -}); - -/** - * Executes the step to install a WP plugin from a remote url via CLI. - */ -Given('I install plugin {string}', async function (pluginUrl) { - await installRemotePlugin(pluginUrl) }); \ No newline at end of file