Skip to content
6 changes: 3 additions & 3 deletions src/data/demo/products.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ export default {
category: 'Men',
summary: 'Regular fit, round neckline, short sleeves. Made of extra long staple pima cotton.',
description: 'Symbol of lightness and delicacy, the hummingbird evokes curiosity and joy. Studio Design\' '
+ 'PolyFaune collection features classic products with colorful patterns, inspired by the traditional japanese '
+ 'origamis. To wear with a chino or jeans. The sublimation textile printing process provides an exceptional '
+ 'color rendering and a color, guaranteed overtime.',
+ 'PolyFaune collection features classic products with colorful patterns, inspired by the traditional japanese '
+ 'origamis. To wear with a chino or jeans. The sublimation textile printing process provides an exceptional '
+ 'color rendering and a color, guaranteed overtime.',
retailPrice: 28.68,
tax: 20,
price: 23.90,
Expand Down
12 changes: 6 additions & 6 deletions src/data/faker/product.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,12 +134,12 @@ export default class FakerProduct {
public deliveryTime: string;

/**
* Constructor for class FakerProduct
* @param productToCreate {Object} Could be used to force the value of some members
* @todo Replace taxRule & tax by FakerTax object
* @todo Rename price to priceTaxIncluded
* @todo Check if retailPrice & finalPrice can be removed
*/
* Constructor for class FakerProduct
* @param productToCreate {Object} Could be used to force the value of some members
* @todo Replace taxRule & tax by FakerTax object
* @todo Rename price to priceTaxIncluded
* @todo Check if retailPrice & finalPrice can be removed
*/
constructor(productToCreate: ProductCreator = {}) {
/** @type {number} ID of the product */
this.id = productToCreate.id || 0;
Expand Down
10 changes: 5 additions & 5 deletions src/data/faker/productReview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,17 @@ export default class FakerProductReview {
public reviewRating: number;

/**
* Constructor for class ProductReview
* @param productReviewToCreate {ProductReviewCreator} Could be used to add a review on a product
*/
* Constructor for class ProductReview
* @param productReviewToCreate {ProductReviewCreator} Could be used to add a review on a product
*/
constructor(productReviewToCreate: ProductReviewCreator = {}) {
/** @type {string} Title of the review */
this.reviewTitle = productReviewToCreate.reviewTitle
|| faker.lorem.sentence(faker.number.int({min: 3, max: 7}));
|| faker.lorem.sentence(faker.number.int({min: 3, max: 7}));

/** @type {string} Content of the review */
this.reviewContent = productReviewToCreate.reviewContent
|| faker.lorem.sentences(faker.number.int({min: 3, max: 10}));
|| faker.lorem.sentences(faker.number.int({min: 3, max: 10}));

/** @type {number} Rating of the review */
this.reviewRating = productReviewToCreate.reviewRating || faker.number.int({min: 1, max: 5});
Expand Down
1 change: 1 addition & 0 deletions src/data/types/product.ts → src/data/types/product.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -279,4 +279,5 @@ export type {
ProductFeatures,
ProductFiles,
ProductCustomizations,
ProductOrderConfirmation,
};
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ export {default as boLocalizationPage} from '@pages/BO/international/localizatio
export {default as boLoginPage} from '@pages/BO/login';
export {default as boModuleManagerPage} from '@pages/BO/modules/moduleManager';
export {default as boModuleManagerAlertsPage} from '@pages/BO/modules/moduleManager/alerts';
export {default as boModuleManagerSelectionPage} from '@pages/BO/modules/moduleManager/selection';
export {default as boModuleManagerUninstalledModulesPage} from '@pages/BO/modules/moduleManager/uninstalledModules';
export {default as boNewExperimentalFeaturesPage} from '@pages/BO/advancedParameters/newExperimentalFeatures';
export {default as boOrdersPage} from '@pages/BO/orders';
Expand All @@ -222,6 +223,7 @@ export {default as boProductsCreateTabSEOPage} from '@pages/BO/catalog/products/
export {default as boProductsCreateTabShippingPage} from '@pages/BO/catalog/products/create/tabShipping';
export {default as boProductsCreateTabStocksPage} from '@pages/BO/catalog/products/create/tabStocks';
export {default as boProductsCreateTabVirtualProductPage} from '@pages/BO/catalog/products/create/tabVirtualProduct';
export {default as boRouterPage} from '@pages/BO/BORouterPage';
export {default as boSearchPage} from '@pages/BO/shopParameters/search';
export {default as boSearchAliasCreatePage} from '@pages/BO/shopParameters/search/alias/create';
export {default as boThemeAdvancedConfigurationPage} from '@pages/BO/design/themeAndLogo/advancedConfiguration';
Expand Down
11 changes: 11 additions & 0 deletions src/interfaces/BO/modules/moduleManager/selection.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import {BOBasePagePageInterface} from '@interfaces/BO';
import type {Page} from '@playwright/test';

export interface ModuleManagerSelectionPageInterface extends BOBasePagePageInterface {
readonly installMessageSuccessful: (moduleTag: string) => string;
readonly pageTitle: string;

goToTabSelection(page: Page): Promise<void>;
goToTabInstalledModules(page: Page): Promise<void>;
installModule(page: Page, moduleTag: string): Promise<boolean>;
}
6 changes: 6 additions & 0 deletions src/interfaces/BO/router.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import type {BOBasePagePageInterface} from '@interfaces/BO/index';
import type {Frame, Page} from '@playwright/test';

export interface BORouterPageInterface extends BOBasePagePageInterface {
goToModuleManagerPage(page: Page): Promise<void>;
}
42 changes: 30 additions & 12 deletions src/pages/BO/BOBasePage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -731,22 +731,31 @@ export default class BOBasePage extends CommonPage implements BOBasePagePageInte
* @returns {Promise<void>}
*/
async goToSubMenu(page: Page, parentSelector: string, linkSelector: string): Promise<void> {
await this.clickSubMenu(page, parentSelector);
await this.scrollTo(page, linkSelector);
await this.clickAndWaitForURL(page, linkSelector);
const psVersion = testContext.getPSVersion();

const shopVersion = testContext.getPSVersion();
let linkActiveClass: string = '-active';

// >= 1.7.8.0
if (semver.gte(shopVersion, '7.8.0')) {
linkActiveClass = 'link-active';
}
// >= 1.7.4.0
if (semver.gte(psVersion, '7.4.0')) {
await this.clickSubMenu(page, parentSelector);
await this.scrollTo(page, linkSelector);
await this.clickAndWaitForURL(page, linkSelector);

// >= 1.7.8.0
if (semver.gte(psVersion, '7.8.0')) {
linkActiveClass = 'link-active';
}

if (await this.isSidebarCollapsed(page)) {
await this.waitForHiddenSelector(page, `${linkSelector}.${linkActiveClass}`);
if (await this.isSidebarCollapsed(page)) {
await this.waitForHiddenSelector(page, `${linkSelector}.${linkActiveClass}`);
} else {
await this.waitForVisibleSelector(page, `${linkSelector}.${linkActiveClass}`);
}
} else {
await this.waitForVisibleSelector(page, `${linkSelector}.${linkActiveClass}`);
await page.locator(parentSelector).hover();
await this.waitForVisibleSelector(page, linkSelector);
await this.clickAndWaitForURL(page, linkSelector);
await this.waitForVisibleSelector(page, `${parentSelector}.${linkActiveClass}`);
}
}

Expand Down Expand Up @@ -1072,7 +1081,16 @@ export default class BOBasePage extends CommonPage implements BOBasePagePageInte
* @return {Promise<string|null>}
*/
async getGrowlMessageContent(page: Page, timeout: number = 10000): Promise<string | null> {
return page.textContent(this.growlMessageBlock, {timeout});
const psVersion = testContext.getPSVersion();
let {growlMessageBlock} = this;

if (semver.lt(psVersion, '8.0.0') && semver.gt(psVersion, '7.4.99')) {
growlMessageBlock = `${this.growlDiv} .growl-message`;
}
if (semver.lt(psVersion, '7.5.0')) {
growlMessageBlock = `${this.growlDefaultDiv} .growl-message`;
}
return page.textContent(growlMessageBlock, {timeout});
}

/**
Expand Down
35 changes: 35 additions & 0 deletions src/pages/BO/BORouterPage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import {BORouterPageInterface} from '@interfaces/BO/router';
import BOBasePage from '@pages/BO/BOBasePage';
import boDashboardPage from '@pages/BO/dashboard/index';
import boModuleManagerPage from '@pages/BO/modules/moduleManager/index';
import boModuleManagerSelectionPage from '@pages/BO/modules/moduleManager/selection';
import testContext from '@utils/testContext';
import type {Page} from 'playwright-core';
import semver from 'semver';

class BORouterPage extends BOBasePage implements BORouterPageInterface {
async goToModuleManagerPage(page: Page): Promise<void> {
const psVersion = testContext.getPSVersion();
const pageTitle = await this.getPageTitle(page);
const boModuleManagerLinkPageTitle = semver.lt(psVersion, '7.4.0')
? boModuleManagerSelectionPage.pageTitle
: boModuleManagerPage.pageTitle;

// Check if we are not already on the page
if (!pageTitle.includes(boModuleManagerLinkPageTitle)) {
await boDashboardPage.goToSubMenu(
page,
boDashboardPage.modulesParentLink,
boDashboardPage.moduleManagerLink,
);
await boDashboardPage.closeSfToolBar(page);
}

if (semver.lt(psVersion, '7.4.0')) {
console.log('goToTabInstalledModules');
await boModuleManagerSelectionPage.goToTabInstalledModules(page);
}
}
}

export default new BORouterPage();
5 changes: 4 additions & 1 deletion src/pages/BO/login/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@ const psVersion = testContext.getPSVersion();

/* eslint-disable global-require, @typescript-eslint/no-var-requires */
function requirePage(): LoginPageInterface {
if (semver.lt(psVersion, '7.3.0')) {
return require('@versions/1.7.2/pages/BO/login');
}
if (semver.lt(psVersion, '8.0.0')) {
return require('@versions/1.7.8/pages/BO/login');
return require('@versions/1.7.8/pages/BO/login').loginPage;
}
if (semver.lt(psVersion, '9.0.0')) {
return require('@versions/8.1/pages/BO/login').loginPage;
Expand Down
3 changes: 3 additions & 0 deletions src/pages/BO/modules/moduleManager/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ import type {ModuleManagerPageInterface} from '@interfaces/BO/modules/moduleMana

/* eslint-disable global-require, @typescript-eslint/no-var-requires */
function requirePage(): ModuleManagerPageInterface {
if (semver.lt(psVersion, '7.5.0')) {
return require('@versions/1.7.4/pages/BO/modules/moduleManager');
}
return require('@versions/develop/pages/BO/modules/moduleManager').moduleManagerPage;
}
/* eslint-enable global-require, @typescript-eslint/no-var-requires */
Expand Down
19 changes: 19 additions & 0 deletions src/pages/BO/modules/moduleManager/selection.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import type {ModuleManagerSelectionPageInterface} from '@interfaces/BO/modules/moduleManager/selection';
import testContext from '@utils/testContext';
import semver from 'semver';

const psVersion = testContext.getPSVersion();

/* eslint-disable global-require, @typescript-eslint/no-var-requires */
function requirePage(): ModuleManagerSelectionPageInterface {
if (semver.gte(psVersion, '7.5.0')) {
return require('@versions/mock/pages/BO/modules/moduleManager/selection');
}
if (semver.gte(psVersion, '7.4.0')) {
return require('@versions/1.7.4/pages/BO/modules/moduleManager/selection').selectionPage;
}
return require('@versions/1.7.3/pages/BO/modules/moduleManager/selection');
}
/* eslint-enable global-require, @typescript-eslint/no-var-requires */

export default requirePage();
31 changes: 24 additions & 7 deletions src/pages/FO/FOBasePage.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
// Import pages
import {FOBasePagePageInterface} from '@interfaces/FO';
import CommonPage from '@pages/commonPage';

import type {Page} from 'playwright';
import utilsTest from '@utils/test';
import type {Locator, Page} from 'playwright';
import semver from 'semver';

/**
* FO parent page, contains functions that can be used on all FO page
Expand Down Expand Up @@ -44,7 +45,9 @@ export default class FOBasePage extends CommonPage implements FOBasePagePageInte

private readonly languageSelectorList: string;

private readonly languageSelectorMenuItemLink: (language: string) => string;
private readonly languageSelectorMenuItemLink: string;

private readonly languageSelectorMenuItemLinkLang: (language: string) => string;

private readonly currencySelectorDiv: string;

Expand Down Expand Up @@ -174,8 +177,9 @@ export default class FOBasePage extends CommonPage implements FOBasePagePageInte
this.defaultLanguageSpan = `${this.languageSelectorDiv} button span`;
this.languageSelectorExpandIcon = `${this.languageSelectorDiv} i.expand-more`;
this.languageSelectorList = `${this.languageSelectorDiv} .js-dropdown.open`;
this.languageSelectorMenuItemLink = (language) => `${this.languageSelectorDiv} ul li `
+ `a[data-iso-code='${language}']`;
this.languageSelectorMenuItemLink = `${this.languageSelectorDiv} ul li a`;
this.languageSelectorMenuItemLinkLang = (language) => `${this.languageSelectorMenuItemLink
}[data-iso-code='${language}']`;
this.currencySelectorDiv = '#_desktop_currency_selector';
this.defaultCurrencySpan = `${this.currencySelectorDiv} button span`;
this.currencySelectorExpandIcon = `${this.currencySelectorDiv} i.expand-more`;
Expand Down Expand Up @@ -409,7 +413,7 @@ export default class FOBasePage extends CommonPage implements FOBasePagePageInte
page.locator(this.languageSelectorExpandIcon).click(),
this.waitForVisibleSelector(page, this.languageSelectorList),
]);
await this.clickAndWaitForLoadState(page, this.languageSelectorMenuItemLink(lang));
await this.clickAndWaitForLoadState(page, this.getLanguageSelector(page, lang));
}

/**
Expand All @@ -434,7 +438,7 @@ export default class FOBasePage extends CommonPage implements FOBasePagePageInte
*/
async languageExists(page: Page, lang: string = 'en'): Promise<boolean> {
await page.locator(this.languageSelectorExpandIcon).click();
return this.elementVisible(page, this.languageSelectorMenuItemLink(lang), 1000);
return this.elementVisible(page, this.getLanguageSelector(page, lang), 1000);
}

/**
Expand Down Expand Up @@ -818,6 +822,19 @@ export default class FOBasePage extends CommonPage implements FOBasePagePageInte
async getRestrictedText(page: Page): Promise<string|null> {
return page.locator(this.restrictedText).textContent();
}

private getLanguageSelector(page: Page, lang: string): string|Locator {
const psVersion = utilsTest.getPSVersion();

// >= 1.7.5.0
if (semver.gte(psVersion, '7.5.0')) {
return this.languageSelectorMenuItemLinkLang(lang);
}

return page.locator(this.languageSelectorMenuItemLink).filter({
hasText: lang === 'en' ? 'English' : 'Français',
});
}
}

module.exports = FOBasePage;
7 changes: 7 additions & 0 deletions src/pages/FO/classic/product/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
import type {FoProductPageInterface} from '@interfaces/FO/product';
import testContext from '@utils/test';
import semver from 'semver';

const psVersion = testContext.getPSVersion();

/* eslint-disable global-require, @typescript-eslint/no-var-requires */
function requirePage(): FoProductPageInterface {
if (semver.lt(psVersion, '9.0.0')) {
return require('@versions/8.1.0/pages/FO/classic/product');
}
return require('@versions/develop/pages/FO/classic/product').productPage;
}
/* eslint-enable global-require, @typescript-eslint/no-var-requires */
Expand Down
Loading