Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@prestashop-core/ui-testing",
"version": "0.0.12",
"version": "0.0.13",
"description": "",
"main": "dist/index.js",
"types": "dist/index.d.ts",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ export interface BOProductsCreateTabCombinationsPageInterface extends BOBasePage
clickOnPreviousCombinationButton(page: Page): Promise<void>;
closeEditCombinationModal(page: Page): Promise<boolean>;
countCombinations(page: Page): Promise<number>;
getCombinationVirtualProductFileName(page: Page): Promise<string>;
setCombinationIsVirtual(page: Page, isVirtual: boolean): Promise<string>;
setCombinationVirtualProductFile(page: Page, filePath: string): Promise<string>;
editCombination(page: Page, combinationData: ProductCombinationOptions, row?: number): Promise<string | null>;
editCombinationFromModal(page: Page, combinationData: ProductCombinationOptions): Promise<string>;
editCombinationRowQuantity(page: Page, row: number, quantity: number): Promise<void>;
Expand Down
1 change: 1 addition & 0 deletions src/interfaces/FO/product/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ export interface FoProductPageInterface extends FOBasePagePageInterface {
isQuantityDisplayed(page: Page): Promise<boolean>;
isUnavailableProductColorDisplayed(page: Page, color: string): Promise<boolean>;
isUnavailableProductSizeDisplayed(page: Page, size: string): Promise<boolean>;
getProductDownloadFileName(page: Page): Promise<string>;
notifyEmailAlert(page: Page, email?: string | null): Promise<string>;
scrollBoxArrowsImages(page: Page, direction: string): Promise<void>;
selectAttributes(page: Page, type: string, attributes: ProductAttribute[], itemNumber?: number): Promise<void>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,14 @@ class CombinationsTab extends BOBasePage implements BOProductsCreateTabCombinati

private readonly editCombinationModalDiscardButton: string;

private readonly editCombinationModalIsVirtualSwitch: (toEnable: number) => string;

private readonly editCombinationModalVirtualProductFileHasFile: (toCheck: number) => string;

private readonly editCombinationModalVirtualProductFileInput: string;

private readonly editCombinationModalVirtualProductFileNameInput: string;

private readonly combinationStockMovementsDate: (row: number) => string;

private readonly combinationStockMovementsEmployeeName: (row: number) => string;
Expand Down Expand Up @@ -332,6 +340,11 @@ class CombinationsTab extends BOBasePage implements BOProductsCreateTabCombinati
this.editCombinationModalCloseButton = `${this.editCombinationModal} footer button.btn-close`;
this.editCombinationCloseModal = `${this.editCombinationEditModal} div.modal-prevent-close div.modal.show`;
this.editCombinationModalDiscardButton = `${this.editCombinationCloseModal} button.btn-primary`;
this.editCombinationModalIsVirtualSwitch = (toEnable: number) => `#combination_form_is_virtual_${toEnable} +i`;
this.editCombinationModalVirtualProductFileHasFile = (toCheck: number) => '#combination_form_virtual_product_file_has_file'
+ `_${toCheck}`;
this.editCombinationModalVirtualProductFileInput = '#combination_form_virtual_product_file_file';
this.editCombinationModalVirtualProductFileNameInput = '#combination_form_virtual_product_file_name';
this.combinationStockMovementsDate = (row: number) => `#combination_form_stock_quantities_stock_movements_${row - 1}_`
+ 'date + span';
this.combinationStockMovementsEmployeeName = (row: number) => '#combination_form_stock_quantities_stock_movements_'
Expand Down Expand Up @@ -705,6 +718,61 @@ class CombinationsTab extends BOBasePage implements BOProductsCreateTabCombinati
return this.elementVisible(combinationFrame!, this.editCombinationModalQuantityInput, 2000);
}

/**
* Toggle the "Is virtual" switch inside the edit combination modal and save.
* @param page {Page} Browser tab
* @param isVirtual {boolean} Target value for the switch
* @returns {Promise<string>} Success message from the growl banner
*/
async setCombinationIsVirtual(page: Page, isVirtual: boolean): Promise<string> {
const combinationFrame: Frame|null = page.frame({url: /sell\/catalog\/products\/combinations/gmi});

await this.setChecked(combinationFrame!, this.editCombinationModalIsVirtualSwitch(isVirtual ? 1 : 0));
await this.waitForSelectorAndClick(page, this.editCombinationModalSaveButton);

return this.getAlertSuccessBlockParagraphContent(combinationFrame!);
}

/**
* Upload a downloadable file for the current combination and save.
* The file is attached to combination's own virtual_product_file, independently
* from the product-level virtual product file.
* @param page {Page} Browser tab
* @param filePath {string} Path of the file to upload
* @returns {Promise<string>} Success message from the growl banner
*/
async setCombinationVirtualProductFile(page: Page, filePath: string): Promise<string> {
const combinationFrame: Frame|null = page.frame({url: /sell\/catalog\/products\/combinations/gmi});

await this.setChecked(combinationFrame!, this.editCombinationModalVirtualProductFileHasFile(1));
await this.waitForVisibleSelector(combinationFrame!, this.editCombinationModalVirtualProductFileInput);
await this.uploadFile(combinationFrame!, this.editCombinationModalVirtualProductFileInput, filePath);
await this.waitForSelectorAndClick(page, this.editCombinationModalSaveButton);

return this.getAlertSuccessBlockParagraphContent(combinationFrame!);
}

/**
* Read the current downloadable filename attached to the combination.
* @param page {Page} Browser tab
* @returns {Promise<string>} File name, or empty string when no file is attached
*/
async getCombinationVirtualProductFileName(page: Page): Promise<string> {
const combinationFrame: Frame|null = page.frame({url: /sell\/catalog\/products\/combinations/gmi});

if (!combinationFrame) {
return '';
}

const fileNameSelector = this.editCombinationModalVirtualProductFileNameInput;

if (!(await this.elementVisible(combinationFrame, fileNameSelector, 2000))) {
return '';
}

return this.getAttributeContent(combinationFrame, this.editCombinationModalVirtualProductFileNameInput, 'value');
}

// Methods for sort
/**
* Sort table by clicking on column name
Expand Down
21 changes: 21 additions & 0 deletions src/versions/develop/pages/FO/classic/product/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ class ProductPage extends FOBasePage implements FoProductPageInterface {

protected productInformationBlock: string;

protected productDownloadFileName: string;

protected productMailAlertsBlock: string;

protected productMailAlertsEmailInput: string;
Expand Down Expand Up @@ -287,6 +289,9 @@ class ProductPage extends FOBasePage implements FoProductPageInterface {

// Product information block
this.productInformationBlock = 'div.product-information';
// Downloadable file offered on the product page for virtual products (product-level or per-combination).
// Falls back gracefully when the theme does not render the block.
this.productDownloadFileName = 'div.product-download-file, .product__additional-info .product-download__filename';
this.productMailAlertsBlock = `${this.productInformationBlock} div.js-mailalert`;
this.productMailAlertsEmailInput = `${this.productMailAlertsBlock} input[type="email"]`;
this.productMailAlertsGDPRLabel = `${this.productMailAlertsBlock} div.gdpr_consent label.psgdpr_consent_message `
Expand Down Expand Up @@ -1347,6 +1352,22 @@ class ProductPage extends FOBasePage implements FoProductPageInterface {
async getNotificationMessage(page: Page): Promise<string> {
return this.getTextContent(page, this.notificationsContainer);
}

/**
* Read the downloadable filename displayed for the currently selected
* combination (or the product itself when there is no combination).
* Returns an empty string when the theme does not render a download block —
* used to assert "no download offered" for physical combinations.
* @param page {Page} Browser tab
* @returns {Promise<string>}
*/
async getProductDownloadFileName(page: Page): Promise<string> {
if (!(await this.elementVisible(page, this.productDownloadFileName, 1000))) {
return '';
}

return (await this.getTextContent(page, this.productDownloadFileName)).trim();
}
}

const productPage = new ProductPage();
Expand Down
Loading