|
| 1 | +// Import pages |
| 2 | +import type {FoModalBlockCartPageInterface} from '@interfaces/FO/modal/blockCart'; |
| 3 | +import FOBasePage from '@pages/FO/FOBasePage'; |
| 4 | + |
| 5 | +// Import data |
| 6 | +import type {ProductAttribute} from '@data/types/product'; |
| 7 | +import type {CartProductDetails} from '@data/types/cart'; |
| 8 | + |
| 9 | +import type {Page} from 'playwright'; |
| 10 | + |
| 11 | +/** |
| 12 | + * Block cart modal, contains functions that can be used on the modal |
| 13 | + * @class |
| 14 | + * @extends FOBasePage |
| 15 | + */ |
| 16 | +class BlockCartModal extends FOBasePage implements FoModalBlockCartPageInterface { |
| 17 | + private readonly blockCartLabel: string; |
| 18 | + |
| 19 | + protected readonly blockCartModalDiv: string; |
| 20 | + |
| 21 | + protected blockCartModalCloseButton: string; |
| 22 | + |
| 23 | + private readonly cartModalProductNameBlock: string; |
| 24 | + |
| 25 | + private readonly cartModalProductPriceBlock: string; |
| 26 | + |
| 27 | + private readonly cartModalProductSizeBlock: string; |
| 28 | + |
| 29 | + private readonly cartModalProductColorBlock: string; |
| 30 | + |
| 31 | + private readonly cartModalProductQuantityBlock: string; |
| 32 | + |
| 33 | + private readonly cartContentBlock: string; |
| 34 | + |
| 35 | + protected cartModalProductsCountBlock: string; |
| 36 | + |
| 37 | + protected cartModalShippingBlock: string; |
| 38 | + |
| 39 | + protected cartModalSubtotalBlock: string; |
| 40 | + |
| 41 | + protected cartModalProductTaxInclBlock: string; |
| 42 | + |
| 43 | + protected cartModalCheckoutLink: string; |
| 44 | + |
| 45 | + protected continueShoppingButton: string; |
| 46 | + |
| 47 | + /** |
| 48 | + * @constructs |
| 49 | + * Setting up texts and selectors to use on home page |
| 50 | + */ |
| 51 | + constructor(theme: string = 'classic') { |
| 52 | + super(theme); |
| 53 | + |
| 54 | + this.blockCartModalDiv = '#blockcart-modal'; |
| 55 | + this.blockCartLabel = '#myModalLabel'; |
| 56 | + this.blockCartModalCloseButton = `${this.blockCartModalDiv} button.close`; |
| 57 | + this.cartModalProductNameBlock = `${this.blockCartModalDiv} .product-name`; |
| 58 | + this.cartModalProductPriceBlock = `${this.blockCartModalDiv} .product-price`; |
| 59 | + this.cartModalProductSizeBlock = `${this.blockCartModalDiv} .size strong`; |
| 60 | + this.cartModalProductColorBlock = `${this.blockCartModalDiv} .color strong`; |
| 61 | + this.cartModalProductQuantityBlock = `${this.blockCartModalDiv} .product-quantity`; |
| 62 | + this.cartContentBlock = `${this.blockCartModalDiv} .cart-content`; |
| 63 | + this.cartModalProductsCountBlock = `${this.cartContentBlock} .cart-products-count`; |
| 64 | + this.cartModalShippingBlock = `${this.cartContentBlock} .shipping.value`; |
| 65 | + this.cartModalSubtotalBlock = `${this.cartContentBlock} .subtotal.value`; |
| 66 | + this.cartModalProductTaxInclBlock = `${this.cartContentBlock} .product-total .value`; |
| 67 | + this.cartModalCheckoutLink = `${this.blockCartModalDiv} div.cart-content-btn a`; |
| 68 | + this.continueShoppingButton = `${this.blockCartModalDiv} div.cart-content-btn button.btn-secondary`; |
| 69 | + } |
| 70 | + |
| 71 | + /** |
| 72 | + * Get block cart modal title |
| 73 | + * @param page {Page} Browser tab |
| 74 | + * @returns {Promise<string>} |
| 75 | + */ |
| 76 | + async getBlockCartModalTitle(page: Page): Promise<string> { |
| 77 | + return this.getTextContent(page, this.blockCartLabel); |
| 78 | + } |
| 79 | + |
| 80 | + /** |
| 81 | + * Is block cart modal visible |
| 82 | + * @param page {Page} Browser tab |
| 83 | + * @returns {Promise<boolean>} |
| 84 | + */ |
| 85 | + async isBlockCartModalVisible(page: Page): Promise<boolean> { |
| 86 | + return this.elementVisible(page, this.blockCartModalDiv, 2000); |
| 87 | + } |
| 88 | + |
| 89 | + /** |
| 90 | + * Get product details from blockCart modal |
| 91 | + * @param page {Page} Browser tab |
| 92 | + * @returns {Promise<CartProductDetails>} |
| 93 | + */ |
| 94 | + async getProductDetailsFromBlockCartModal(page: Page): Promise<CartProductDetails> { |
| 95 | + return { |
| 96 | + name: await this.getTextContent(page, this.cartModalProductNameBlock), |
| 97 | + price: parseFloat((await this.getTextContent(page, this.cartModalProductPriceBlock)).replace('€', '')), |
| 98 | + quantity: await this.getNumberFromText(page, this.cartModalProductQuantityBlock), |
| 99 | + cartProductsCount: await this.getNumberFromText(page, this.cartModalProductsCountBlock), |
| 100 | + cartSubtotal: parseFloat((await this.getTextContent(page, this.cartModalSubtotalBlock)).replace('€', '')), |
| 101 | + cartShipping: await this.getTextContent(page, this.cartModalShippingBlock), |
| 102 | + totalTaxIncl: parseFloat((await this.getTextContent(page, this.cartModalProductTaxInclBlock)).replace('€', '')), |
| 103 | + }; |
| 104 | + } |
| 105 | + |
| 106 | + /** |
| 107 | + * Get product attributes from block cart modal |
| 108 | + * @param page {Page} Browser tab |
| 109 | + * @returns {Promise<ProductAttribute[]>} |
| 110 | + */ |
| 111 | + async getProductAttributesFromBlockCartModal(page: Page): Promise<ProductAttribute[]> { |
| 112 | + return [ |
| 113 | + { |
| 114 | + name: 'size', |
| 115 | + value: await this.getTextContent(page, this.cartModalProductSizeBlock), |
| 116 | + }, |
| 117 | + { |
| 118 | + name: 'color', |
| 119 | + value: await this.getTextContent(page, this.cartModalProductColorBlock), |
| 120 | + }, |
| 121 | + ]; |
| 122 | + } |
| 123 | + |
| 124 | + /** |
| 125 | + * Click on proceed to checkout after adding product to cart (in modal homePage) |
| 126 | + * @param page {Page} Browser tab |
| 127 | + * @return {Promise<void>} |
| 128 | + */ |
| 129 | + async proceedToCheckout(page: Page): Promise<void> { |
| 130 | + await this.clickAndWaitForURL(page, this.cartModalCheckoutLink); |
| 131 | + await page.waitForLoadState('domcontentloaded'); |
| 132 | + } |
| 133 | + |
| 134 | + /** |
| 135 | + * Click on continue shopping |
| 136 | + * @param page {Page} Browser tab |
| 137 | + * @returns {Promise<boolean>} |
| 138 | + */ |
| 139 | + async continueShopping(page: Page): Promise<boolean> { |
| 140 | + await this.waitForSelectorAndClick(page, this.continueShoppingButton); |
| 141 | + |
| 142 | + return this.elementNotVisible(page, this.blockCartModalDiv, 2000); |
| 143 | + } |
| 144 | + |
| 145 | + /** |
| 146 | + * Close block cart modal |
| 147 | + * @param page {Page} Browser tab |
| 148 | + * @param clickOutside {boolean} True if we need to click outside to close the modal |
| 149 | + * @returns {Promise<boolean>} |
| 150 | + */ |
| 151 | + async closeBlockCartModal(page: Page, clickOutside: boolean = false): Promise<boolean> { |
| 152 | + if (clickOutside) { |
| 153 | + await page.waitForTimeout(1000); |
| 154 | + await page.mouse.click(5, 5); |
| 155 | + } else { |
| 156 | + await this.waitForSelectorAndClick(page, this.blockCartModalCloseButton); |
| 157 | + } |
| 158 | + return this.elementNotVisible(page, this.blockCartModalDiv, 1000); |
| 159 | + } |
| 160 | +} |
| 161 | + |
| 162 | +const blockCartModal = new BlockCartModal(); |
| 163 | +export {blockCartModal, BlockCartModal}; |
0 commit comments