diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b213db3..47f397f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -29,9 +29,17 @@ jobs: node-version: '18' - name: Create .env file run: | - echo "USERNAME=${{ secrets.USERNAME }}" >> .env - echo "PASSWORD=${{ secrets.PASSWORD }}" >> .env - + echo "USERNAME=${{ secrets.USERNAME }}" >> .env + echo "USERNAME1=${{ secrets.USERNAME1 }}" >> .env + echo "PASSWORD=${{ secrets.PASSWORD }}" >> .env + echo "NEW_PASSWORD=${{ secrets.NEW_PASSWORD }}" >> .env + echo "FIRST_NAME=${{ secrets.FIRST_NAME }}" >> .env + echo "STREET_NAME=${{ secrets.STREET_NAME }}" >> .env + echo "CITY=${{ secrets.CITY }}" >> .env + echo "STATE=${{ secrets.STATE }}" >> .env + echo "COUNTRY=${{ secrets.COUNTRY }}" >> .env + echo "ZIP_CODE=${{ secrets.ZIP_CODE }}" >> .env + - name: Cache npm dependencies uses: actions/cache@v3 with: diff --git a/pages/AllPages.js b/pages/AllPages.js index 8bee63e..f9f7c91 100644 --- a/pages/AllPages.js +++ b/pages/AllPages.js @@ -1,30 +1,30 @@ -import LoginPage from "./LoginPage"; -import InventoryPage from "./InventoryPage"; -import SignupPage from "./SignupPage"; -import HomePage from "./HomePage"; -import AllProductsPage from "./AllProductsPage"; -import ProductDetailsPage from "./ProductDetailsPage"; -import CartPage from "./CartPage"; -import CheckoutPage from "./CheckoutPage"; -import OrderPage from "./OrderPage"; // Import OrderPage -import UserPage from "./UserPage"; // Import UserPage -import OrderDetailsPage from "./OrderDetailsPage"; - -class AllPages { - constructor(page) { - this.page = page; - this.loginPage = new LoginPage(page); - this.inventoryPage = new InventoryPage(page); - this.signupPage = new SignupPage(page); - this.homePage = new HomePage(page); - this.allProductsPage = new AllProductsPage(page); - this.productDetailsPage = new ProductDetailsPage(page); - this.cartPage = new CartPage(page); - this.checkoutPage = new CheckoutPage(page); - this.orderPage = new OrderPage(page); // Instantiate OrderPage - this.userPage = new UserPage(page); // Instantiate UserPage - this.orderDetailsPage = new OrderDetailsPage(page); - } -} - +import LoginPage from "./LoginPage"; +import InventoryPage from "./InventoryPage"; +import SignupPage from "./SignupPage"; +import HomePage from "./HomePage"; +import AllProductsPage from "./AllProductsPage"; +import ProductDetailsPage from "./ProductDetailsPage"; +import CartPage from "./CartPage"; +import CheckoutPage from "./CheckoutPage"; +import OrderPage from "./OrderPage"; // Import OrderPage +import UserPage from "./UserPage"; // Import UserPage +import OrderDetailsPage from "./OrderDetailsPage"; + +class AllPages { + constructor(page) { + this.page = page; + this.loginPage = new LoginPage(page); + this.inventoryPage = new InventoryPage(page); + this.signupPage = new SignupPage(page); + this.homePage = new HomePage(page); + this.allProductsPage = new AllProductsPage(page); + this.productDetailsPage = new ProductDetailsPage(page); + this.cartPage = new CartPage(page); + this.checkoutPage = new CheckoutPage(page); + this.orderPage = new OrderPage(page); // Instantiate OrderPage + this.userPage = new UserPage(page); // Instantiate UserPage + this.orderDetailsPage = new OrderDetailsPage(page); + } +} + export default AllPages; \ No newline at end of file diff --git a/pages/AllProductsPage.js b/pages/AllProductsPage.js index bed01c5..4fbeddd 100644 --- a/pages/AllProductsPage.js +++ b/pages/AllProductsPage.js @@ -1,64 +1,65 @@ -import BasePage from './BasePage.js'; -import { expect } from '@playwright/test'; - -class AllProductsPage extends BasePage{ - - /** - * @param {import('@playwright/test').Page} page - */ - constructor(page) { - super(page); - this.page = page; - } - - locators = { - allProductsTitle: `//h1[text()="All Products"]`, - nthProduct: `[href*="/product-detail/product"]`, - nthProductName: `[href*="/product-detail/product"] h2`, - nthProductPrice: `[href*="/product-detail/product"] p`, - nthProductReviewCount: `[href*="/product-detail/product"] h2 + div span.text-sm`, - nthProductWishlistIcon: '[aria-label="heart"]', - nthProductWishlistIconCount: '.bg-orange-100' - } - - async assertAllProductsTitle() { - await expect(this.page.locator(this.locators.allProductsTitle)).toBeVisible(); - } - - getNthProduct(n) { - return this.page.locator(this.locators.nthProduct).nth(n - 1) - } - - async clickNthProduct(n) { - await this.getNthProduct(n).click(); - } - - getNthProductName(n) { - return this.page.locator(this.locators.nthProductName).nth(n - 1).textContent(); - } - - getNthProductPrice(n) { - return this.page.locator(this.locators.nthProductPrice).nth(n - 1).textContent(); - } - - getNthProductReviewCount(n) { - return this.page.locator(this.locators.nthProductReviewCount).nth(n - 1).textContent(); - } - - getNthProductWishlistIcon(n) { - return this.page.locator(this.locators.nthProductWishlistIcon).nth(n - 1) - } - - async clickNthProductWishlistIcon(n) { - await this.getNthProduct(n).hover() - await this.getNthProductWishlistIcon(n).click(); - await expect(this.page.getByText('Added to the wishlist')).toBeVisible(); - } - - getNthProductWishlistIconCount(n) { - return this.page.locator(this.locators.nthProductWishlistIconCount).nth(n - 1); - } - -} - +import BasePage from './BasePage.js'; +import { expect } from '@playwright/test'; + +class AllProductsPage extends BasePage{ + + /** + * @param {import('@playwright/test').Page} page + */ + constructor(page) { + super(page); + this.page = page; + } + + locators = { + allProductsTitle: `//h1[text()="All Products"]`, + nthProduct: `[href*="/product-detail/product"]`, + nthProductName: `[href*="/product-detail/product"] h2`, + nthProductPrice: `[href*="/product-detail/product"] p`, + nthProductReviewCount: `[href*="/product-detail/product"] h2 + div span.text-sm`, + nthProductWishlistIcon: '[aria-label="heart"]', + nthProductWishlistIconCount: '.bg-orange-100' + + } + + async assertAllProductsTitle() { + await expect(this.page.locator(this.locators.allProductsTitle)).toBeVisible(); + } + + getNthProduct(n) { + return this.page.locator(this.locators.nthProduct).nth(n - 1) + } + + async clickNthProduct(n) { + await this.getNthProduct(n).click(); + } + + getNthProductName(n) { + return this.page.locator(this.locators.nthProductName).nth(n - 1).textContent(); + } + + getNthProductPrice(n) { + return this.page.locator(this.locators.nthProductPrice).nth(n - 1).textContent(); + } + + getNthProductReviewCount(n) { + return this.page.locator(this.locators.nthProductReviewCount).nth(n - 1).textContent(); + } + + getNthProductWishlistIcon(n) { + return this.page.locator(this.locators.nthProductWishlistIcon).nth(n - 1) + } + + async clickNthProductWishlistIcon(n) { + await this.getNthProduct(n).hover() + await this.getNthProductWishlistIcon(n).click(); + await expect(this.page.getByText('Added to the wishlist')).toBeVisible(); + } + + getNthProductWishlistIconCount(n) { + return this.page.locator(this.locators.nthProductWishlistIconCount).nth(n - 1); + } + +} + export default AllProductsPage; \ No newline at end of file diff --git a/pages/BasePage.js b/pages/BasePage.js index 2ff51bf..b890848 100644 --- a/pages/BasePage.js +++ b/pages/BasePage.js @@ -1,20 +1,20 @@ -import { Page } from '@playwright/test'; - -class BasePage { - /** - * @param {Page} page - */ - constructor(page) { - this.page = page; - } - - async navigateTo(url) { - await this.page.goto(url); - } - - async getPageTitle() { - return await this.page.title(); - } -} - +import { Page } from '@playwright/test'; + +class BasePage { + /** + * @param {Page} page + */ + constructor(page) { + this.page = page; + } + + async navigateTo(url) { + await this.page.goto(url); + } + + async getPageTitle() { + return await this.page.title(); + } +} + export default BasePage; \ No newline at end of file diff --git a/pages/CartPage.js b/pages/CartPage.js index d7f853a..aa92fb6 100644 --- a/pages/CartPage.js +++ b/pages/CartPage.js @@ -1,128 +1,128 @@ -import BasePage from './BasePage.js'; -import { expect } from '@playwright/test'; - -class CartPage extends BasePage{ - - /** - * @param {import('@playwright/test').Page} page - */ - constructor(page) { - super(page); - this.page = page; - } - - locators = { - yourCartTitle: 'h2:has-text("Your Cart")', - cartItemImage: '[data-testid="cart-item-image"]', - cartItemName: '[data-testid="cart-item-header"]', - cartItemQuantity: '[data-testid="item-quantity"]', - increaseQuantityButton: '[data-testid="increase-quantity"]', - decreaseQuantityButton: '[data-testid="decrease-quantity"]', - cartItemPrice: '[data-testid="item-price"]', - removeCartItem: '[data-testid="remove-item"]', - subtotalLabel: '[data-testid="subtotal-label"]', - subtotalValue: '[data-testid="subtotal-value"]', - shippingLabel: '[data-testid="shipping-label"]', - shippingValue: '[data-testid="shipping-value"]', - totalLabel: '[data-testid="total-label"]', - totalValue: '[data-testid="total-value"]', - checkoutButton: '[data-testid="checkout-button"]', - viewCartButton: '[data-testid="view-cart-button"]', - shoppingCartIcon: "//*[name()='svg'][.//*[name()='path' and contains(@d,'M0 24C0 10')]]", - } - - async assertYourCartTitle() { - await expect(this.page.locator(this.locators.yourCartTitle)).toBeVisible({ timeout: 10000 }); - } - - getCartItemImage() { - return this.page.locator(this.locators.cartItemImage) - } - - getCartItemName() { - return this.page.locator(this.locators.cartItemName) - } - - getCartItemQuantity() { - return this.page.locator(this.locators.cartItemQuantity) - } - - getIncreaseQuantityButton() { - return this.page.locator(this.locators.increaseQuantityButton).first(); - } - - async clickIncreaseQuantityButton() { - await this.getIncreaseQuantityButton().click(); - } - - getDecreaseQuantityButton() { - return this.page.locator(this.locators.decreaseQuantityButton) - } - - async clickDecreaseQuantityButton() { - await this.getDecreaseQuantityButton().click(); - } - - getCartItemPrice() { - return this.page.locator(this.locators.cartItemPrice) - } - - getRemoveCartItem() { - return this.page.locator(this.locators.removeCartItem) - } - - getSubtotalLabel() { - return this.page.locator(this.locators.subtotalLabel) - } - - getSubtotalValue() { - return this.page.locator(this.locators.subtotalValue) - } - - getShippingLabel() { - return this.page.locator(this.locators.shippingLabel) - } - - getShippingValue() { - return this.page.locator(this.locators.shippingValue) - } - - getTotalLabel() { - return this.page.locator(this.locators.totalLabel) - } - - getTotalValue() { - return this.page.locator(this.locators.totalValue); - } - - getCheckoutButton() { - return this.page.locator(this.locators.checkoutButton) - } - - async clickCheckoutButton() { - await this.getCheckoutButton().click(); - } - - getViewCartButton() { - return this.page.locator(this.locators.viewCartButton) - } - - async clickViewCartButton() { - await this.getViewCartButton().click(); - } - - async clickOnCartIcon() { - await this.page.locator(this.locators.shoppingCartIcon).click({ force: true }); - } - - async verifyCartItemVisible(productName) { - await expect(this.page.locator(this.locators.cartItemName)).toBeVisible(); - await expect(this.page.locator(this.locators.cartItemName)).toHaveText(productName); - } - - async clickOnCheckoutButton() { - await this.page.locator(this.locators.checkoutButton).click({ force: true }); - } -} - +import BasePage from './BasePage.js'; +import { expect } from '@playwright/test'; + +class CartPage extends BasePage{ + + /** + * @param {import('@playwright/test').Page} page + */ + constructor(page) { + super(page); + this.page = page; + } + + locators = { + yourCartTitle: 'h2:has-text("Your Cart")', + cartItemImage: '[data-testid="cart-item-image"]', + cartItemName: '[data-testid="cart-item-header"]', + cartItemQuantity: '[data-testid="item-quantity"]', + increaseQuantityButton: '[data-testid="increase-quantity"]', + decreaseQuantityButton: '[data-testid="decrease-quantity"]', + cartItemPrice: '[data-testid="item-price"]', + removeCartItem: '[data-testid="remove-item"]', + subtotalLabel: '[data-testid="subtotal-label"]', + subtotalValue: '[data-testid="subtotal-value"]', + shippingLabel: '[data-testid="shipping-label"]', + shippingValue: '[data-testid="shipping-value"]', + totalLabel: '[data-testid="total-label"]', + totalValue: '[data-testid="total-value"]', + checkoutButton: '[data-testid="checkout-button"]', + viewCartButton: '[data-testid="view-cart-button"]', + shoppingCartIcon: `[data-testid="header-cart-icon"]`, + } + + async assertYourCartTitle() { + await expect(this.page.locator(this.locators.yourCartTitle)).toBeVisible({ timeout: 10000 }); + } + + getCartItemImage() { + return this.page.locator(this.locators.cartItemImage) + } + + getCartItemName() { + return this.page.locator(this.locators.cartItemName) + } + + getCartItemQuantity() { + return this.page.locator(this.locators.cartItemQuantity) + } + + getIncreaseQuantityButton() { + return this.page.locator(this.locators.increaseQuantityButton).first(); + } + + async clickIncreaseQuantityButton() { + await this.getIncreaseQuantityButton().click(); + } + + getDecreaseQuantityButton() { + return this.page.locator(this.locators.decreaseQuantityButton) + } + + async clickDecreaseQuantityButton() { + await this.getDecreaseQuantityButton().click(); + } + + getCartItemPrice() { + return this.page.locator(this.locators.cartItemPrice) + } + + getRemoveCartItem() { + return this.page.locator(this.locators.removeCartItem) + } + + getSubtotalLabel() { + return this.page.locator(this.locators.subtotalLabel) + } + + getSubtotalValue() { + return this.page.locator(this.locators.subtotalValue) + } + + getShippingLabel() { + return this.page.locator(this.locators.shippingLabel) + } + + getShippingValue() { + return this.page.locator(this.locators.shippingValue) + } + + getTotalLabel() { + return this.page.locator(this.locators.totalLabel) + } + + getTotalValue() { + return this.page.locator(this.locators.totalValue); + } + + getCheckoutButton() { + return this.page.locator(this.locators.checkoutButton) + } + + async clickCheckoutButton() { + await this.getCheckoutButton().click(); + } + + getViewCartButton() { + return this.page.locator(this.locators.viewCartButton) + } + + async clickViewCartButton() { + await this.getViewCartButton().click(); + } + + async clickOnCartIcon() { + await this.page.locator(this.locators.shoppingCartIcon).click({ force: true }); + } + + async verifyCartItemVisible(productName) { + await expect(this.page.locator(this.locators.cartItemName)).toBeVisible(); + await expect(this.page.locator(this.locators.cartItemName)).toHaveText(productName); + } + + async clickOnCheckoutButton() { + await this.page.locator(this.locators.checkoutButton).click({ force: true }); + } +} + export default CartPage; \ No newline at end of file diff --git a/pages/CheckoutPage.js b/pages/CheckoutPage.js index d6d3930..b2240d5 100644 --- a/pages/CheckoutPage.js +++ b/pages/CheckoutPage.js @@ -1,262 +1,262 @@ -import BasePage from './BasePage.js'; -import { expect } from '@playwright/test'; - -class CheckoutPage extends BasePage { - - /** - * @param {import('@playwright/test').Page} page - */ - constructor(page) { - super(page); - this.page = page; - } - - locators = { - shippingAddress: { - checkoutTitle: 'checkout-title', - checkoutShippingAddressTitle: 'checkout-shipping-address-title', - checkoutShippingAddressFirstName: 'checkout-first-name-input', - checkoutShippingAddressEmail: 'checkout-email-input', - checkoutShippingAddressCity: 'checkout-city-input', - checkoutShippingAddressState: 'checkout-state-input', - checkoutShippingAddressStreetAddress: 'checkout-street-input', - checkoutShippingAddressZipCode: 'checkout-zip-code-input', - checkoutShippingAddressCountry: 'checkout-country-input', - checkoutCancelButton: 'checkout-cancel-button', - checkoutSaveAddressButton: 'checkout-save-address-button', - }, - paymentMethod: { - checkoutPaymentMethodTitle: 'checkout-payment-method-title', - checkoutCreditCardButton: 'checkout-credit-card-button', - checkoutDebitCardButton: 'checkout-debit-card-button', - checkoutNetbankingButton: 'checkout-netbanking-button', - checkoutCodButton: 'checkout-cod-button', - checkoutCardNumberInput: 'checkout-card-number-input', - checkoutCardHolderNameInput: 'checkout-cardholder-name-input', - checkoutExpirationDateMonthInput: 'checkout-expiration-date-month-input', - checkoutExpirationDateYearInput: 'checkout-expiration-date-year-input', - checkoutCvvInput: 'checkout-cvv-input', - }, - orderSummary: { - checkoutOrderSummaryTitle: 'checkout-order-summary-title', - checkoutOrderSummaryImage: '[data-testid="checkout-order-summary-title"] + div img', - checkoutProductName: 'checkout-product-header', - checkoutProductQuantity: 'checkout-product-quantity', - checkoutProductPrice: 'checkout-product-price', - checkoutSubtotalValue: 'checkout-subtotal-value', - checkoutShippingValue: 'checkout-shipping-value', - checkoutTotalValue: 'checkout-total-value', - checkoutPlaceOrderButton: 'checkout-place-order-button', - checkoutContinueShoppingButton: 'checkout-continue-shopping-button' - }, - // New locators - checkoutTitle: "h1[data-testid='checkout-title']", - productNameInCheckout: "//h3[normalize-space()='{}']", - cashOnDeliveryButton: "//button[normalize-space()='Cash on Delivery']", - cashOnDeliveryText: "//p[normalize-space()='Cash on Delivery']", - placeOrderButton: "//button[normalize-space()='Place Order']", - orderSuccessMessage: "//p[contains(text(), 'Your order was placed successf')]", - orderItemNameConfirmation: "p[data-testid='order-item-name']", - } - - // **************** Shipping Address **************** // - async assertCheckoutTitle() { - await expect(this.page.getByTestId(this.locators.shippingAddress.checkoutTitle)).toBeVisible({ timeout: 10000 }); - } - - getShippingAddressTitle() { - return this.page.getByTestId(this.locators.shippingAddress.checkoutShippingAddressTitle) - } - - getShippingAddressFirstName() { - return this.page.getByTestId(this.locators.shippingAddress.checkoutShippingAddressFirstName) - } - - getShippingAddressEmail() { - return this.page.getByTestId(this.locators.shippingAddress.checkoutShippingAddressEmail) - } - - getShippingAddressCity() { - return this.page.getByTestId(this.locators.shippingAddress.checkoutShippingAddressCity) - } - - getShippingAddressState() { - return this.page.getByTestId(this.locators.shippingAddress.checkoutShippingAddressState) - } - - getShippingAddressStreetAddress() { - return this.page.getByTestId(this.locators.shippingAddress.checkoutShippingAddressStreetAddress) - } - - getShippingAddressZipCode() { - return this.page.getByTestId(this.locators.shippingAddress.checkoutShippingAddressZipCode) - } - - getShippingAddressCountry() { - return this.page.getByTestId(this.locators.shippingAddress.checkoutShippingAddressCountry) - } - - getShippingAddressCancelButton() { - return this.page.getByTestId(this.locators.shippingAddress.checkoutCancelButton) - } - - async clickCancelButton() { - await this.getShippingAddressCancelButton().click(); - } - - getSaveAddressButton() { - return this.page.getByTestId(this.locators.shippingAddress.checkoutSaveAddressButton) - } - - async clickSaveAddressButton() { - await this.getSaveAddressButton().click(); - } - - async fillShippingAddress(firstName, email, city, state, streetAddress, zipCode, country) { - await this.getShippingAddressFirstName().fill(firstName); - await this.getShippingAddressEmail().fill(email); - await this.getShippingAddressCity().fill(city); - await this.getShippingAddressState().fill(state); - await this.getShippingAddressStreetAddress().fill(streetAddress); - await this.getShippingAddressZipCode().fill(zipCode); - await this.getShippingAddressCountry().fill(country); - } - - async assertAddressAddedToast() { - await expect(this.page.getByText('Address added successfully')).toBeVisible({ timeout: 10000 }); - } - - // **************** Payment Method **************** // - - getPaymentMethodTitle() { - return this.page.getByTestId(this.locators.paymentMethod.checkoutPaymentMethodTitle) - } - - getCreditCardButton() { - return this.page.getByTestId(this.locators.paymentMethod.checkoutCreditCardButton) - } - - getDebitCardButton() { - return this.page.getByTestId(this.locators.paymentMethod.checkoutDebitCardButton) - } - - getNetbankingButton() { - return this.page.getByTestId(this.locators.paymentMethod.checkoutNetbankingButton) - } - - getCodButton() { - return this.page.getByTestId(this.locators.paymentMethod.checkoutCodButton) - } - - async clickCodButton() { - await this.getCodButton().click(); - } - - getCardNumberInput() { - return this.page.getByTestId(this.locators.paymentMethod.checkoutCardNumberInput) - } - - getCardHolderNameInput() { - return this.page.getByTestId(this.locators.paymentMethod.checkoutCardHolderNameInput) - } - - getExpirationDateMonthInput() { - return this.page.getByTestId(this.locators.paymentMethod.checkoutExpirationDateMonthInput) - } - - getExpirationDateYearInput() { - return this.page.getByTestId(this.locators.paymentMethod.checkoutExpirationDateYearInput) - } - - getCvvInput() { - return this.page.getByTestId(this.locators.paymentMethod.checkoutCvvInput) - } - - // ************************** Order Summary ************************** // - - getOrderSummaryTitle() { - return this.page.getByTestId(this.locators.orderSummary.checkoutOrderSummaryTitle) - } - - async assertOrderSummaryTitle() { - await expect(this.page.getByTestId(this.locators.orderSummary.checkoutOrderSummaryTitle)).toBeVisible(); - } - - getOrderSummaryImage() { - return this.page.locator(this.locators.orderSummary.checkoutOrderSummaryImage) - } - - getOrderSummaryProductName() { - return this.page.getByTestId(this.locators.orderSummary.checkoutProductName) - } - - getOrderSummaryProductQuantity() { - return this.page.getByTestId(this.locators.orderSummary.checkoutProductQuantity) - } - - getOrderSummaryProductPrice() { - return this.page.getByTestId(this.locators.orderSummary.checkoutProductPrice) - } - - getOrderSummarySubtotalValue() { - return this.page.getByTestId(this.locators.orderSummary.checkoutSubtotalValue).textContent(); - } - - getOrderSummaryShippingValue() { - return this.page.getByTestId(this.locators.orderSummary.checkoutShippingValue) - } - - getOrderSummaryTotalValue() { - return this.page.getByTestId(this.locators.orderSummary.checkoutTotalValue) - } - - getPlaceOrderButton() { - return this.page.getByTestId(this.locators.orderSummary.checkoutPlaceOrderButton) - } - - async clickPlaceOrderButton() { - await this.getPlaceOrderButton().click(); - } - - getContinueShoppingButton() { - return this.page.getByTestId(this.locators.orderSummary.checkoutContinueShoppingButton) - } - - async clickContinueShoppingButton() { - await this.getContinueShoppingButton().click(); - } - - async verifyCheckoutTitle() { - await expect(this.page.locator(this.locators.checkoutTitle)).toBeVisible(); - } - - async verifyProductInCheckout(productName) { - const locator = this.page.locator(this.locators.productNameInCheckout.replace('{}', productName)).nth(1); - await expect(locator).toBeVisible(); - await expect(locator).toHaveText(productName); - } - - async selectCashOnDelivery() { - await this.page.locator(this.locators.cashOnDeliveryButton).click({ force: true }); - } - - async verifyCashOnDeliverySelected() { - await expect(this.page.locator(this.locators.cashOnDeliveryText)).toBeVisible(); - } - - async clickOnPlaceOrder() { - await this.page.locator(this.locators.placeOrderButton).click({ force: true }); - } - - async verifyOrderPlacedSuccessfully() { - await expect(this.page.locator(this.locators.orderSuccessMessage)).toBeVisible(); - } - - async verifyOrderItemName(productName) { - await expect(this.page.locator(this.locators.orderItemNameConfirmation)).toBeVisible(); - await expect(this.page.locator(this.locators.orderItemNameConfirmation)).toHaveText(productName); - } - -} - +import BasePage from './BasePage.js'; +import { expect } from '@playwright/test'; + +class CheckoutPage extends BasePage { + + /** + * @param {import('@playwright/test').Page} page + */ + constructor(page) { + super(page); + this.page = page; + } + + locators = { + shippingAddress: { + checkoutTitle: 'checkout-title', + checkoutShippingAddressTitle: 'checkout-shipping-address-title', + checkoutShippingAddressFirstName: 'checkout-first-name-input', + checkoutShippingAddressEmail: 'checkout-email-input', + checkoutShippingAddressCity: 'checkout-city-input', + checkoutShippingAddressState: 'checkout-state-input', + checkoutShippingAddressStreetAddress: 'checkout-street-input', + checkoutShippingAddressZipCode: 'checkout-zip-code-input', + checkoutShippingAddressCountry: 'checkout-country-input', + checkoutCancelButton: 'checkout-cancel-button', + checkoutSaveAddressButton: 'checkout-save-address-button', + }, + paymentMethod: { + checkoutPaymentMethodTitle: 'checkout-payment-method-title', + checkoutCreditCardButton: 'checkout-credit-card-button', + checkoutDebitCardButton: 'checkout-debit-card-button', + checkoutNetbankingButton: 'checkout-netbanking-button', + checkoutCodButton: 'checkout-cod-button', + checkoutCardNumberInput: 'checkout-card-number-input', + checkoutCardHolderNameInput: 'checkout-cardholder-name-input', + checkoutExpirationDateMonthInput: 'checkout-expiration-date-month-input', + checkoutExpirationDateYearInput: 'checkout-expiration-date-year-input', + checkoutCvvInput: 'checkout-cvv-input', + }, + orderSummary: { + checkoutOrderSummaryTitle: 'checkout-order-summary-title', + checkoutOrderSummaryImage: '[data-testid="checkout-order-summary-title"] + div img', + checkoutProductName: 'checkout-product-header', + checkoutProductQuantity: 'checkout-product-quantity', + checkoutProductPrice: 'checkout-product-price', + checkoutSubtotalValue: 'checkout-subtotal-value', + checkoutShippingValue: 'checkout-shipping-value', + checkoutTotalValue: 'checkout-total-value', + checkoutPlaceOrderButton: 'checkout-place-order-button', + checkoutContinueShoppingButton: 'checkout-continue-shopping-button' + }, + // New locators + checkoutTitle: "h1[data-testid='checkout-title']", + productNameInCheckout: "//h3[normalize-space()='{}']", + cashOnDeliveryButton: "//button[normalize-space()='Cash on Delivery']", + cashOnDeliveryText: "//p[normalize-space()='Cash on Delivery']", + placeOrderButton: "//button[normalize-space()='Place Order']", + orderSuccessMessage: "//p[contains(text(), 'Your order was placed successf')]", + orderItemNameConfirmation: "p[data-testid='order-item-name']", + } + + // **************** Shipping Address **************** // + async assertCheckoutTitle() { + await expect(this.page.getByTestId(this.locators.shippingAddress.checkoutTitle)).toBeVisible({ timeout: 10000 }); + } + + getShippingAddressTitle() { + return this.page.getByTestId(this.locators.shippingAddress.checkoutShippingAddressTitle) + } + + getShippingAddressFirstName() { + return this.page.getByTestId(this.locators.shippingAddress.checkoutShippingAddressFirstName) + } + + getShippingAddressEmail() { + return this.page.getByTestId(this.locators.shippingAddress.checkoutShippingAddressEmail) + } + + getShippingAddressCity() { + return this.page.getByTestId(this.locators.shippingAddress.checkoutShippingAddressCity) + } + + getShippingAddressState() { + return this.page.getByTestId(this.locators.shippingAddress.checkoutShippingAddressState) + } + + getShippingAddressStreetAddress() { + return this.page.getByTestId(this.locators.shippingAddress.checkoutShippingAddressStreetAddress) + } + + getShippingAddressZipCode() { + return this.page.getByTestId(this.locators.shippingAddress.checkoutShippingAddressZipCode) + } + + getShippingAddressCountry() { + return this.page.getByTestId(this.locators.shippingAddress.checkoutShippingAddressCountry) + } + + getShippingAddressCancelButton() { + return this.page.getByTestId(this.locators.shippingAddress.checkoutCancelButton) + } + + async clickCancelButton() { + await this.getShippingAddressCancelButton().click(); + } + + getSaveAddressButton() { + return this.page.getByTestId(this.locators.shippingAddress.checkoutSaveAddressButton) + } + + async clickSaveAddressButton() { + await this.getSaveAddressButton().click(); + } + + async fillShippingAddress(firstName, email, city, state, streetAddress, zipCode, country) { + await this.getShippingAddressFirstName().fill(firstName); + await this.getShippingAddressEmail().fill(email); + await this.getShippingAddressCity().fill(city); + await this.getShippingAddressState().fill(state); + await this.getShippingAddressStreetAddress().fill(streetAddress); + await this.getShippingAddressZipCode().fill(zipCode); + await this.getShippingAddressCountry().fill(country); + } + + async assertAddressAddedToast() { + await expect(this.page.getByText('Address added successfully')).toBeVisible({ timeout: 10000 }); + } + + // **************** Payment Method **************** // + + getPaymentMethodTitle() { + return this.page.getByTestId(this.locators.paymentMethod.checkoutPaymentMethodTitle) + } + + getCreditCardButton() { + return this.page.getByTestId(this.locators.paymentMethod.checkoutCreditCardButton) + } + + getDebitCardButton() { + return this.page.getByTestId(this.locators.paymentMethod.checkoutDebitCardButton) + } + + getNetbankingButton() { + return this.page.getByTestId(this.locators.paymentMethod.checkoutNetbankingButton) + } + + getCodButton() { + return this.page.getByTestId(this.locators.paymentMethod.checkoutCodButton) + } + + async clickCodButton() { + await this.getCodButton().click(); + } + + getCardNumberInput() { + return this.page.getByTestId(this.locators.paymentMethod.checkoutCardNumberInput) + } + + getCardHolderNameInput() { + return this.page.getByTestId(this.locators.paymentMethod.checkoutCardHolderNameInput) + } + + getExpirationDateMonthInput() { + return this.page.getByTestId(this.locators.paymentMethod.checkoutExpirationDateMonthInput) + } + + getExpirationDateYearInput() { + return this.page.getByTestId(this.locators.paymentMethod.checkoutExpirationDateYearInput) + } + + getCvvInput() { + return this.page.getByTestId(this.locators.paymentMethod.checkoutCvvInput) + } + + // ************************** Order Summary ************************** // + + getOrderSummaryTitle() { + return this.page.getByTestId(this.locators.orderSummary.checkoutOrderSummaryTitle) + } + + async assertOrderSummaryTitle() { + await expect(this.page.getByTestId(this.locators.orderSummary.checkoutOrderSummaryTitle)).toBeVisible(); + } + + getOrderSummaryImage() { + return this.page.locator(this.locators.orderSummary.checkoutOrderSummaryImage) + } + + getOrderSummaryProductName() { + return this.page.getByTestId(this.locators.orderSummary.checkoutProductName) + } + + getOrderSummaryProductQuantity() { + return this.page.getByTestId(this.locators.orderSummary.checkoutProductQuantity) + } + + getOrderSummaryProductPrice() { + return this.page.getByTestId(this.locators.orderSummary.checkoutProductPrice) + } + + getOrderSummarySubtotalValue() { + return this.page.getByTestId(this.locators.orderSummary.checkoutSubtotalValue).textContent(); + } + + getOrderSummaryShippingValue() { + return this.page.getByTestId(this.locators.orderSummary.checkoutShippingValue) + } + + getOrderSummaryTotalValue() { + return this.page.getByTestId(this.locators.orderSummary.checkoutTotalValue) + } + + getPlaceOrderButton() { + return this.page.getByTestId(this.locators.orderSummary.checkoutPlaceOrderButton) + } + + async clickPlaceOrderButton() { + await this.getPlaceOrderButton().click(); + } + + getContinueShoppingButton() { + return this.page.getByTestId(this.locators.orderSummary.checkoutContinueShoppingButton) + } + + async clickContinueShoppingButton() { + await this.getContinueShoppingButton().click(); + } + + async verifyCheckoutTitle() { + await expect(this.page.locator(this.locators.checkoutTitle)).toBeVisible(); + } + + async verifyProductInCheckout(productName) { + const locator = this.page.locator(this.locators.productNameInCheckout.replace('{}', productName)).nth(1); + await expect(locator).toBeVisible(); + await expect(locator).toHaveText(productName); + } + + async selectCashOnDelivery() { + await this.page.locator(this.locators.cashOnDeliveryButton).click({ force: true }); + } + + async verifyCashOnDeliverySelected() { + await expect(this.page.locator(this.locators.cashOnDeliveryText)).toBeVisible(); + } + + async clickOnPlaceOrder() { + await this.page.locator(this.locators.placeOrderButton).click({ force: true }); + } + + async verifyOrderPlacedSuccessfully() { + await expect(this.page.locator(this.locators.orderSuccessMessage)).toBeVisible(); + } + + async verifyOrderItemName(productName) { + await expect(this.page.locator(this.locators.orderItemNameConfirmation)).toBeVisible(); + await expect(this.page.locator(this.locators.orderItemNameConfirmation)).toHaveText(productName); + } + +} + export default CheckoutPage; \ No newline at end of file diff --git a/pages/HomePage.js b/pages/HomePage.js index a2603df..72c55b3 100644 --- a/pages/HomePage.js +++ b/pages/HomePage.js @@ -1,50 +1,93 @@ -import BasePage from './BasePage.js'; -import { expect } from '@playwright/test'; - -class HomePage extends BasePage{ - - /** - * @param {import('@playwright/test').Page} page - */ - constructor(page) { - super(page); - this.page = page; - } - - locators = { - navbar: { - homeNav: `//li[text()="Home"]`, - aboutUsNav: `//li[text()="About Us"]`, - contactUsNav: `//li[text()="Contact Us"]`, - allProductsNav: `//li[text()="All Products"]`, - showNowButton: `//a[@href="/products"]/button[text()="Shop Now"]`, - } - } - - getHomeNav() { - return this.page.locator(this.locators.navbar.homeNav).first(); - } - - getAboutUsNav() { - return this.page.locator(this.locators.navbar.aboutUsNav).first(); - } - - getContactUsNav() { - return this.page.locator(this.locators.navbar.contactUsNav).first(); - } - - getAllProductsNav() { - return this.page.locator(this.locators.navbar.allProductsNav).first(); - } - - async clickAllProductsNav() { - await this.getAllProductsNav().click(); - } - - getShowNowButton() { - return this.page.locator(this.locators.navbar.showNowButton); - } - -} - +import BasePage from './BasePage.js'; +import { expect } from '@playwright/test'; + +class HomePage extends BasePage{ + + /** + * @param {import('@playwright/test').Page} page + */ + constructor(page) { + super(page); + this.page = page; + } + + locators = { + navbar: { + homeNav: `//li[text()="Home"]`, + aboutUsNav: `//li[text()="About Us"]`, + contactUsNav: `//li[text()="Contact Us"]`, + allProductsNav: `//li[text()="All Products"]`, + showNowButton: `//a[@href="/products"]/button[text()="Shop Now"]`, + ProductImage: `img[src="/products/Speaker.png"][alt="JBL Charge 4 Bluetooth Speaker"]`, + addToCartButton: `[data-testid="add-to-cart-button"]`, + AddCartNotification: `div[role="status"][aria-live="polite"]:has-text("Added to the cart")`, + priceRangeSlider2 : `[data-testid="all-products-price-range-input-1"]`, + priceRangeSlider1 : `[data-testid="all-products-price-range-input-0"]`, + filterButton : `[data-testid="all-products-filter-toggle"]` + } + } + + async clickOnFilterButton() { + await this.page.locator(this.locators.navbar.filterButton).click(); + } + + async AdjustPriceRangeSlider(minPrice, maxPrice) { + await this.page.locator(this.locators.navbar.priceRangeSlider1).fill(minPrice); + await this.page.locator(this.locators.navbar.priceRangeSlider2).fill(maxPrice); + } + + async clickOnShopNowButton() { + await this.page.locator(this.locators.navbar.showNowButton).click(); + } + + getProductImage() { + return this.page.locator(this.locators.navbar.ProductImage); + } + + async clickProductImage() { + await this.getProductImage().click(); + } + + getAddToCartButton() { + return this.page.locator(this.locators.navbar.addToCartButton); + } + + async clickAddToCartButton() { + await this.getAddToCartButton().click(); + } + + getAddCartNotification() { + return this.page.locator(this.locators.navbar.AddCartNotification); + } + + async validateAddCartNotification() { + await expect(this.getAddCartNotification()).toBeVisible(); + } + + getHomeNav() { + return this.page.locator(this.locators.navbar.homeNav).first(); + } + + getAboutUsNav() { + return this.page.locator(this.locators.navbar.aboutUsNav).first(); + } + + getContactUsNav() { + return this.page.locator(this.locators.navbar.contactUsNav).first(); + } + + getAllProductsNav() { + return this.page.locator(this.locators.navbar.allProductsNav).first(); + } + + async clickAllProductsNav() { + await this.getAllProductsNav().click(); + } + + getShowNowButton() { + return this.page.locator(this.locators.navbar.showNowButton); + } + +} + export default HomePage; \ No newline at end of file diff --git a/pages/InventoryPage.js b/pages/InventoryPage.js index 321cbbb..1832d5b 100644 --- a/pages/InventoryPage.js +++ b/pages/InventoryPage.js @@ -1,64 +1,83 @@ -import BasePage from './BasePage'; -import { expect } from '@playwright/test'; - -class InventoryPage extends BasePage { - - /** - * - * @param {import('@playwright/test').Page} page - */ - constructor(page) { - super(page); - this.page = page; - } - - locators = { - shopNowBtn: `(//button[text()='Shop Now'])[1]`, - allProductsTitle: `//h1[text()='All Products']`, - searchProductInput: `input[placeholder='Search products...']`, - selectProduct: `[class="relative pt-4 px-4"]`, - productTitle: `(//h1[text()='JBL Charge 4 Bluetooth Speaker'])[1]`, - wishlistIcon: `//button[.//span[@aria-label='heart']]`, - allProductsLink: "(//li[normalize-space()='All Products'])[1]", - addToCartIcon: "//*[name()='svg'][.//*[name()='path' and contains(@d,'M832 312H6')]]", - goProHero10BlackTitle: "//h2[normalize-space()='GoPro HERO10 Black']", - continueShoppingButton: "//button[normalize-space()='Continue Shopping']", - - } - - async clickOnShopNowButton() { - await this.page.click(this.locators.shopNowBtn); - await expect(this.page.locator(this.locators.allProductsTitle)).toBeVisible(); - } - async searchProduct(productName) { - await this.page.fill(this.locators.searchProductInput, productName); - await this.page.keyboard.press('Enter'); - } - async selectProduct() { - await this.page.click(this.locators.selectProduct); - await expect(this.page.locator(this.locators.productTitle)).toBeVisible(); - } - async addToWishlist() { - await this.page.click(this.locators.wishlistIcon); - // Add any additional assertions or actions needed after adding to wishlist - } - - async clickOnAllProductsLink() { - await this.page.locator(this.locators.allProductsLink).click({ force: true }); - } - - async clickOnAddToCartIcon() { - await this.page.locator(this.locators.addToCartIcon).click({ force: true }); - } - - async verifyProductTitleVisible(productName) { - await expect(this.page.locator(`//h2[normalize-space()='${productName}']`)).toHaveText(productName); - } - - async clickOnContinueShopping() { - await this.page.locator(this.locators.continueShoppingButton).click({ force: true }); - } - -} - +import BasePage from './BasePage'; +import { expect } from '@playwright/test'; + +class InventoryPage extends BasePage { + + /** + * + * @param {import('@playwright/test').Page} page + */ + constructor(page) { + super(page); + this.page = page; + } + + locators = { + shopNowBtn: `(//button[text()='Shop Now'])[1]`, + allProductsTitle: `//h1[text()='All Products']`, + searchProductInput: `input[placeholder='Search products...']`, + selectProduct: `[class="relative pt-4 px-4"]`, + productTitle: `(//h1[text()='JBL Charge 4 Bluetooth Speaker'])[1]`, + wishlistIcon: `//button[.//span[@aria-label='heart']]`, + allProductsLink: "(//li[normalize-space()='All Products'])[1]", + addToCartIcon: "//*[name()='svg'][.//*[name()='path' and contains(@d,'M832 312H6')]]", + goProHero10BlackTitle: "//h2[normalize-space()='GoPro HERO10 Black']", + continueShoppingButton: "//button[normalize-space()='Continue Shopping']", + wishlistNotification: `div[role="status"][aria-live="polite"]:has-text("Added to the wishlist")`, + wishlistIconHeader : `[data-testid="header-wishlist-count"]`, + assertWishlistPage : `[data-testid="wishlist-title"]`, + wishlistAddToCard : `//button[normalize-space()='Add to Cart']` + + } + + async clickOnShopNowButton() { + await this.page.click(this.locators.shopNowBtn); + await expect(this.page.locator(this.locators.allProductsTitle)).toBeVisible(); + } + async searchProduct(productName) { + await this.page.fill(this.locators.searchProductInput, productName); + await this.page.keyboard.press('Enter'); + } + async selectProduct() { + await this.page.click(this.locators.selectProduct); + await expect(this.page.locator(this.locators.productTitle)).toBeVisible(); + } + async addToWishlist() { + await this.page.click(this.locators.wishlistIcon); + // Add any additional assertions or actions needed after adding to wishlist + } + async assertWishlistIcon() { + await expect(this.page.locator(this.locators.wishlistNotification)).toBeVisible(); + } + + async clickOnWishlistIconHeader() { + await this.page.locator(this.locators.wishlistIconHeader).click({ force: true }); + } + + async assertWishlistPage() { + await expect(this.page.locator(this.locators.assertWishlistPage)).toBeVisible(); + } + + async clickOnWishlistAddToCard() { + await this.page.locator(this.locators.wishlistAddToCard).click({ force: true }); + } + + async clickOnAllProductsLink() { + await this.page.locator(this.locators.allProductsLink).click({ force: true }); + } + + async clickOnAddToCartIcon() { + await this.page.locator(this.locators.addToCartIcon).click({ force: true }); + } + + async verifyProductTitleVisible(productName) { + await expect(this.page.locator(`//h2[normalize-space()='${productName}']`)).toHaveText(productName); + } + + async clickOnContinueShopping() { + await this.page.locator(this.locators.continueShoppingButton).click({ force: true }); + } + +} + export default InventoryPage; \ No newline at end of file diff --git a/pages/LoginPage.js b/pages/LoginPage.js index ac55306..22e010d 100644 --- a/pages/LoginPage.js +++ b/pages/LoginPage.js @@ -1,84 +1,84 @@ -import BasePage from './BasePage.js'; -import { expect } from '@playwright/test'; - -class LoginPage extends BasePage{ - - /** - * @param {import('@playwright/test').Page} page - */ - constructor(page) { - super(page); - this.page = page; - } - - locators = { - loginPageTitle: `//h2[text()=' Sign In']`, - userName: `[placeholder="Your email address"]`, - password: `[placeholder="Your password"]`, - loginButton: `//button[text()='Sign in']`, - invalidLoginError: '[data-test="error"]', - userIcon: `//*[name()='svg'][.//*[name()='path' and contains(@d,'M25.1578 1')]]`, - logoutButton: `//p[text()='Log Out']`, - signupLink: `Sign up`, - successSignInMessage: `Logged in successfully`, - } - - async navigateToLoginPage() { - await this.navigateTo('/'); - } - - getLoginPageTitle() { - return this.page.locator(this.locators.loginPageTitle); - } - - getUserNameInput() { - return this.page.locator(this.locators.userName); - } - - getPasswordInput() { - return this.page.locator(this.locators.password); - } - - getLoginButton() { - return this.page.locator(this.locators.loginButton); - } - - async clickUserIcon() { - await this.page.locator(this.locators.userIcon).click(); - } - - async clickOnUserProfileIcon() { - await this.page.locator(this.locators.userIcon).click(); - } - - async assertLoginPage() { - await expect(this.getLoginPageTitle()).toBeVisible(); - await expect(this.getUserNameInput()).toBeVisible(); - await expect(this.getPasswordInput()).toBeVisible(); - await expect(this.getLoginButton()).toBeVisible(); - } - - async login(username, password) { - await this.page.fill(this.locators.userName, username); - await this.page.fill(this.locators.password, password); - await this.page.click(this.locators.loginButton); - await this.page.waitForTimeout(2000); - } - - async clickOnLogoutButton() { - await this.page.locator(this.locators.logoutButton).click(); - } - async validateSignInPage() { - await expect(this.getLoginPageTitle()).toBeVisible(); - } - - async clickOnSignupLink() { - await this.page.getByText(this.locators.signupLink).click(); - } - - async verifySuccessSignIn() { - await expect(this.page.getByText(this.locators.successSignInMessage)).toBeVisible({ timeout: 10000 }); - } -} - +import BasePage from './BasePage.js'; +import { expect } from '@playwright/test'; + +class LoginPage extends BasePage{ + + /** + * @param {import('@playwright/test').Page} page + */ + constructor(page) { + super(page); + this.page = page; + } + + locators = { + loginPageTitle: `//h2[text()=' Sign In']`, + userName: `[placeholder="Your email address"]`, + password: `[placeholder="Your password"]`, + loginButton: `//button[text()='Sign in']`, + invalidLoginError: '[data-test="error"]', + userIcon: `//*[name()='svg'][.//*[name()='path' and contains(@d,'M25.1578 1')]]`, + logoutButton: `//p[text()='Log Out']`, + signupLink: `Sign up`, + successSignInMessage: `Logged in successfully`, + } + + async navigateToLoginPage() { + await this.navigateTo('/'); + } + + getLoginPageTitle() { + return this.page.locator(this.locators.loginPageTitle); + } + + getUserNameInput() { + return this.page.locator(this.locators.userName); + } + + getPasswordInput() { + return this.page.locator(this.locators.password); + } + + getLoginButton() { + return this.page.locator(this.locators.loginButton); + } + + async clickUserIcon() { + await this.page.locator(this.locators.userIcon).click(); + } + + async clickOnUserProfileIcon() { + await this.page.locator(this.locators.userIcon).click(); + } + + async assertLoginPage() { + await expect(this.getLoginPageTitle()).toBeVisible(); + await expect(this.getUserNameInput()).toBeVisible(); + await expect(this.getPasswordInput()).toBeVisible(); + await expect(this.getLoginButton()).toBeVisible(); + } + + async login(username, password) { + await this.page.fill(this.locators.userName, username); + await this.page.fill(this.locators.password, password); + await this.page.click(this.locators.loginButton); + await this.page.waitForTimeout(2000); + } + + async clickOnLogoutButton() { + await this.page.locator(this.locators.logoutButton).click(); + } + async validateSignInPage() { + await expect(this.getLoginPageTitle()).toBeVisible(); + } + + async clickOnSignupLink() { + await this.page.getByText(this.locators.signupLink).click(); + } + + async verifySuccessSignIn() { + await expect(this.page.getByText(this.locators.successSignInMessage)).toBeVisible({ timeout: 10000 }); + } +} + export default LoginPage; \ No newline at end of file diff --git a/pages/OrderDetailsPage.js b/pages/OrderDetailsPage.js index bf75992..0fa4c2f 100644 --- a/pages/OrderDetailsPage.js +++ b/pages/OrderDetailsPage.js @@ -1,149 +1,149 @@ -import BasePage from './BasePage.js'; -import { expect } from '@playwright/test'; - -class OrderDetailsPage extends BasePage{ - - /** - * @param {import('@playwright/test').Page} page - */ - constructor(page) { - super(page); - this.page = page; - } - - locators = { - orderDetailsTitle: 'order-details-title', - orderId: 'order-id', - orderPlacedName: 'order-placed-name', - orderPlacedMessage: 'order-placed-message', - orderPlacedDate: 'order-placed-date', - backToHomeButton: 'back-to-home', - orderInformation: { - orderInformationTitle: 'order-information-title', - orderConfirmedTitle:'order-confirmed-title', - orderConfirmedMessage:'order-confirmed-message', - shippingDetailsTitle:'shipping-details-title', - shippingEmailValue:'shipping-email-value', - paymentMethodAmount:'payment-method-amount', - deliveryAddressLabel:'delivery-address-label', - deliveryAddressValue:'delivery-address-value', - continueShoppingButton:'continue-shopping-button' - }, - orderSummary: { - orderSummaryTitle:'order-summary-title', - orderSummaryProductName:'order-item-name', - orderSummaryProductQuantity:'order-item-quantity', - orderSummaryProductPrice:'order-item-price', - subtotalValue:'subtotal-value', - shippingValue:'shipping-value', - totalValue:'total-value' - } - } - - async assertOrderDetailsTitle() { - await expect(this.page.getByTestId(this.locators.orderDetailsTitle)).toBeVisible(); - } - - getOrderId() { - return this.page.getByTestId(this.locators.orderId) - } - - getBackToHomeButton() { - return this.page.getByTestId(this.locators.backToHomeButton) - } - - async clickBackToHomeButton() { - await this.getBackToHomeButton().click(); - } - - async assertOrderPlacedName() { - await expect(this.page.getByTestId(this.locators.orderPlacedName)).toBeVisible(); - } - - async assertOrderPlacedMessage() { - await expect(this.page.getByTestId(this.locators.orderPlacedMessage)).toBeVisible(); - } - - async assertOrderPlacedDate() { - await expect(this.page.getByTestId(this.locators.orderPlacedDate)).toBeVisible(); - } - - async assertOrderInformationTitle() { - await expect(this.page.getByTestId(this.locators.orderInformation.orderInformationTitle)).toBeVisible(); - } - - - // ****************************** Order Information ****************************** // - async assertOrderConfirmedTitle() { - await expect(this.page.getByTestId(this.locators.orderInformation.orderConfirmedTitle)).toBeVisible(); - } - - async assertOrderConfirmedMessage() { - await expect(this.page.getByTestId(this.locators.orderInformation.orderConfirmedMessage)).toBeVisible(); - } - - - async assertShippingDetailsTitle() { - await expect(this.page.getByTestId(this.locators.orderInformation.shippingDetailsTitle)).toBeVisible(); - } - - async assertShippingEmailValue(email) { - await expect(this.page.getByTestId(this.locators.orderInformation.shippingEmailValue)).toContainText(email); - } - - async assertPaymentMethodAmount(amount) { - await expect(this.page.getByTestId(this.locators.orderInformation.paymentMethodAmount)).toContainText(amount); - } - - async assertDeliveryAddressLabel() { - await expect(this.page.getByTestId(this.locators.orderInformation.deliveryAddressLabel)).toBeVisible(); - } - - async assertDeliveryAddressValue() { - await expect(this.page.getByTestId(this.locators.orderInformation.deliveryAddressValue)).toBeVisible(); - } - - getContinueShoppingButton() { - return this.page.getByTestId(this.locators.orderInformation.continueShoppingButton) - } - - async clickContinueShoppingButton() { - await this.getContinueShoppingButton().click(); - } - - async assertContinueShoppingButton() { - await expect(this.getContinueShoppingButton()).toBeVisible(); - } - - // ****************************** Order Summary ****************************** // - async assertOrderSummaryTitle() { - await expect(this.page.getByTestId(this.locators.orderSummary.orderSummaryTitle)).toBeVisible(); - } - - async assertOrderSummaryProductName(productName) { - await expect(this.page.getByTestId(this.locators.orderSummary.orderSummaryProductName)).toContainText(productName); - } - - async assertOrderSummaryProductQuantity(quantity) { - await expect(this.page.getByTestId(this.locators.orderSummary.orderSummaryProductQuantity)).toContainText(quantity); - } - - async assertOrderSummaryProductPrice(price) { - await expect(this.page.getByTestId(this.locators.orderSummary.orderSummaryProductPrice)).toContainText(price); - } - - async assertOrderSummarySubtotalValue(subtotal) { - await expect(this.page.getByTestId(this.locators.orderSummary.subtotalValue)).toContainText(subtotal); - } - - async assertOrderSummaryShippingValue(shipping) { - await expect(this.page.getByTestId(this.locators.orderSummary.shippingValue)).toContainText(shipping); - } - - async assertOrderSummaryTotalValue(total) { - await expect(this.page.getByTestId(this.locators.orderSummary.totalValue)).toContainText(total); - } - -} - +import BasePage from './BasePage.js'; +import { expect } from '@playwright/test'; + +class OrderDetailsPage extends BasePage{ + + /** + * @param {import('@playwright/test').Page} page + */ + constructor(page) { + super(page); + this.page = page; + } + + locators = { + orderDetailsTitle: 'order-details-title', + orderId: 'order-id', + orderPlacedName: 'order-placed-name', + orderPlacedMessage: 'order-placed-message', + orderPlacedDate: 'order-placed-date', + backToHomeButton: 'back-to-home', + orderInformation: { + orderInformationTitle: 'order-information-title', + orderConfirmedTitle:'order-confirmed-title', + orderConfirmedMessage:'order-confirmed-message', + shippingDetailsTitle:'shipping-details-title', + shippingEmailValue:'shipping-email-value', + paymentMethodAmount:'payment-method-amount', + deliveryAddressLabel:'delivery-address-label', + deliveryAddressValue:'delivery-address-value', + continueShoppingButton:'continue-shopping-button' + }, + orderSummary: { + orderSummaryTitle:'order-summary-title', + orderSummaryProductName:'order-item-name', + orderSummaryProductQuantity:'order-item-quantity', + orderSummaryProductPrice:'order-item-price', + subtotalValue:'subtotal-value', + shippingValue:'shipping-value', + totalValue:'total-value' + } + } + + async assertOrderDetailsTitle() { + await expect(this.page.getByTestId(this.locators.orderDetailsTitle)).toBeVisible(); + } + + getOrderId() { + return this.page.getByTestId(this.locators.orderId) + } + + getBackToHomeButton() { + return this.page.getByTestId(this.locators.backToHomeButton) + } + + async clickBackToHomeButton() { + await this.getBackToHomeButton().click(); + } + + async assertOrderPlacedName() { + await expect(this.page.getByTestId(this.locators.orderPlacedName)).toBeVisible(); + } + + async assertOrderPlacedMessage() { + await expect(this.page.getByTestId(this.locators.orderPlacedMessage)).toBeVisible(); + } + + async assertOrderPlacedDate() { + await expect(this.page.getByTestId(this.locators.orderPlacedDate)).toBeVisible(); + } + + async assertOrderInformationTitle() { + await expect(this.page.getByTestId(this.locators.orderInformation.orderInformationTitle)).toBeVisible(); + } + + + // ****************************** Order Information ****************************** // + async assertOrderConfirmedTitle() { + await expect(this.page.getByTestId(this.locators.orderInformation.orderConfirmedTitle)).toBeVisible(); + } + + async assertOrderConfirmedMessage() { + await expect(this.page.getByTestId(this.locators.orderInformation.orderConfirmedMessage)).toBeVisible(); + } + + + async assertShippingDetailsTitle() { + await expect(this.page.getByTestId(this.locators.orderInformation.shippingDetailsTitle)).toBeVisible(); + } + + async assertShippingEmailValue(email) { + await expect(this.page.getByTestId(this.locators.orderInformation.shippingEmailValue)).toContainText(email); + } + + async assertPaymentMethodAmount(amount) { + await expect(this.page.getByTestId(this.locators.orderInformation.paymentMethodAmount)).toContainText(amount); + } + + async assertDeliveryAddressLabel() { + await expect(this.page.getByTestId(this.locators.orderInformation.deliveryAddressLabel)).toBeVisible(); + } + + async assertDeliveryAddressValue() { + await expect(this.page.getByTestId(this.locators.orderInformation.deliveryAddressValue)).toBeVisible(); + } + + getContinueShoppingButton() { + return this.page.getByTestId(this.locators.orderInformation.continueShoppingButton) + } + + async clickContinueShoppingButton() { + await this.getContinueShoppingButton().click(); + } + + async assertContinueShoppingButton() { + await expect(this.getContinueShoppingButton()).toBeVisible(); + } + + // ****************************** Order Summary ****************************** // + async assertOrderSummaryTitle() { + await expect(this.page.getByTestId(this.locators.orderSummary.orderSummaryTitle)).toBeVisible(); + } + + async assertOrderSummaryProductName(productName) { + await expect(this.page.getByTestId(this.locators.orderSummary.orderSummaryProductName)).toContainText(productName); + } + + async assertOrderSummaryProductQuantity(quantity) { + await expect(this.page.getByTestId(this.locators.orderSummary.orderSummaryProductQuantity)).toContainText(quantity); + } + + async assertOrderSummaryProductPrice(price) { + await expect(this.page.getByTestId(this.locators.orderSummary.orderSummaryProductPrice)).toContainText(price); + } + + async assertOrderSummarySubtotalValue(subtotal) { + await expect(this.page.getByTestId(this.locators.orderSummary.subtotalValue)).toContainText(subtotal); + } + + async assertOrderSummaryShippingValue(shipping) { + await expect(this.page.getByTestId(this.locators.orderSummary.shippingValue)).toContainText(shipping); + } + + async assertOrderSummaryTotalValue(total) { + await expect(this.page.getByTestId(this.locators.orderSummary.totalValue)).toContainText(total); + } + +} + export default OrderDetailsPage; \ No newline at end of file diff --git a/pages/OrderPage.js b/pages/OrderPage.js index c2525c8..08d26db 100644 --- a/pages/OrderPage.js +++ b/pages/OrderPage.js @@ -1,94 +1,94 @@ -import BasePage from './BasePage.js'; -import { expect } from '@playwright/test'; - -class OrderPage extends BasePage { - - /** - * @param {import('@playwright/test').Page} page - */ - constructor(page) { - super(page); - this.page = page; - } - - locators = { - myOrdersTab: "//p[normalize-space()='My Orders']", - myOrdersTitle: "h2[data-testid='my-orders-title']", - viewDetailsButton: "(//button[normalize-space()='View'])[1]", - orderDetailsTitle: "//h1[normalize-space()='Order Details']", - orderItemName: "p[data-testid='order-item-name']", - orderItemQuantity: "p:has-text('Qty:')", - orderTotalValue: "p[data-testid='total-value']", - orderStatusDisplay: "div[class*='badge']", - cancelOrderButton: "button:has-text('Cancel')", - confirmCancellationButton: "//button[normalize-space()='Yes, Cancel Order']", - toasterMessage: "div[id='_rht_toaster'] > div > div", - paginationButton: "//button[normalize-space()='{}']", - productNameInOrderList: "h3[normalize-space()='{}']", - priceAndQuantityInOrderList: "div[normalize-space()='{}']", - orderStatusInList: "div[normalize-space()='{}']", - myOrdersCount: "span[data-testid='my-orders-count']", - } - - async clickOnMyOrdersTab() { - await this.page.locator(this.locators.myOrdersTab).click({ force: true }); - } - - async verifyMyOrdersTitle() { - await expect(this.page.locator(this.locators.myOrdersTitle)).toBeVisible(); - } - - async clickViewDetailsButton(orderIndex = 1) { - await this.page.locator(`(//button[normalize-space()='View'])[${orderIndex}]`).click(); - } - - async verifyOrderDetailsTitle() { - await expect(this.page.locator(this.locators.orderDetailsTitle)).toBeVisible(); - } - - async verifyOrderSummary(productName, quantity, amount, status) { - await expect(this.page.locator(this.locators.orderItemName)).toHaveText(productName); - await expect(this.page.locator(this.locators.orderItemQuantity)).toContainText(`Qty: ${quantity}`); - await expect(this.page.locator(this.locators.orderTotalValue)).toContainText(amount); - await expect(this.page.locator(this.locators.orderStatusDisplay)).toHaveText(status); - } - - async clickCancelOrderButton(buttonIndex = 1) { - await this.page.locator(`(//button[normalize-space()='Cancel'])[${buttonIndex}]`).click({ force: true }); - } - - async confirmCancellation() { - await this.page.locator(this.locators.confirmCancellationButton).click({ force: true }); - } - - async verifyCancellationConfirmationMessage() { - await expect(this.page.locator(this.locators.toasterMessage)).toBeVisible(); - await expect(this.page.locator(this.locators.toasterMessage)).toContainText('canceled successfully'); - } - - async verifyOrderStatusIsCanceled(productName) { - await expect(this.page.locator(`//h3[normalize-space()='${productName}']`).locator('xpath=./ancestor::div[contains(@class, "card")]//div[contains(@class, "badge")]')).toHaveText('Canceled'); - } - - async clickOnPaginationButton(pageNumber) { - await this.page.locator(this.locators.paginationButton.replace('{}', pageNumber)).click({ force: true }); - } - - async verifyProductInOrderList(productName) { - await expect(this.page.locator(this.locators.productNameInOrderList.replace('{}', productName))).toBeVisible(); - } - - async verifyPriceAndQuantityInOrderList(priceAndQuantity) { - await expect(this.page.locator(this.locators.priceAndQuantityInOrderList.replace('{}', priceAndQuantity))).toBeVisible(); - } - - async verifyOrderStatusInList(status, productName) { - await expect(this.page.locator(`//h3[normalize-space()='${productName}']`).locator('xpath=./ancestor::div[contains(@class, "card")]//div[contains(@class, "badge")]')).toHaveText(status); - } - - async verifyMyOrdersCount() { - await expect(this.page.locator(this.locators.myOrdersCount)).toBeVisible(); - } -} - -export default OrderPage; +import BasePage from './BasePage.js'; +import { expect } from '@playwright/test'; + +class OrderPage extends BasePage { + + /** + * @param {import('@playwright/test').Page} page + */ + constructor(page) { + super(page); + this.page = page; + } + + locators = { + myOrdersTab: "//p[normalize-space()='My Orders']", + myOrdersTitle: "h2[data-testid='my-orders-title']", + viewDetailsButton: "(//button[normalize-space()='View'])[1]", + orderDetailsTitle: "//h1[normalize-space()='Order Details']", + orderItemName: "p[data-testid='order-item-name']", + orderItemQuantity: "p:has-text('Qty:')", + orderTotalValue: "p[data-testid='total-value']", + orderStatusDisplay: "div[class*='badge']", + cancelOrderButton: "button:has-text('Cancel')", + confirmCancellationButton: "//button[normalize-space()='Yes, Cancel Order']", + toasterMessage: "div[id='_rht_toaster'] > div > div", + paginationButton: "//button[normalize-space()='{}']", + productNameInOrderList: "h3[normalize-space()='{}']", + priceAndQuantityInOrderList: "div[normalize-space()='{}']", + orderStatusInList: "div[normalize-space()='{}']", + myOrdersCount: "span[data-testid='my-orders-count']", + } + + async clickOnMyOrdersTab() { + await this.page.locator(this.locators.myOrdersTab).click({ force: true }); + } + + async verifyMyOrdersTitle() { + await expect(this.page.locator(this.locators.myOrdersTitle)).toBeVisible(); + } + + async clickViewDetailsButton(orderIndex = 1) { + await this.page.locator(`(//button[normalize-space()='View'])[${orderIndex}]`).click(); + } + + async verifyOrderDetailsTitle() { + await expect(this.page.locator(this.locators.orderDetailsTitle)).toBeVisible(); + } + + async verifyOrderSummary(productName, quantity, amount, status) { + await expect(this.page.locator(this.locators.orderItemName)).toHaveText(productName); + await expect(this.page.locator(this.locators.orderItemQuantity)).toContainText(`Qty: ${quantity}`); + await expect(this.page.locator(this.locators.orderTotalValue)).toContainText(amount); + await expect(this.page.locator(this.locators.orderStatusDisplay)).toHaveText(status); + } + + async clickCancelOrderButton(buttonIndex = 1) { + await this.page.locator(`(//button[normalize-space()='Cancel'])[${buttonIndex}]`).click({ force: true }); + } + + async confirmCancellation() { + await this.page.locator(this.locators.confirmCancellationButton).click({ force: true }); + } + + async verifyCancellationConfirmationMessage() { + await expect(this.page.locator(this.locators.toasterMessage)).toBeVisible(); + await expect(this.page.locator(this.locators.toasterMessage)).toContainText('canceled successfully'); + } + + async verifyOrderStatusIsCanceled(productName) { + await expect(this.page.locator(`//h3[normalize-space()='${productName}']`).locator('xpath=./ancestor::div[contains(@class, "card")]//div[contains(@class, "badge")]')).toHaveText('Canceled'); + } + + async clickOnPaginationButton(pageNumber) { + await this.page.locator(this.locators.paginationButton.replace('{}', pageNumber)).click({ force: true }); + } + + async verifyProductInOrderList(productName) { + await expect(this.page.locator(this.locators.productNameInOrderList.replace('{}', productName))).toBeVisible(); + } + + async verifyPriceAndQuantityInOrderList(priceAndQuantity) { + await expect(this.page.locator(this.locators.priceAndQuantityInOrderList.replace('{}', priceAndQuantity))).toBeVisible(); + } + + async verifyOrderStatusInList(status, productName) { + await expect(this.page.locator(`//h3[normalize-space()='${productName}']`).locator('xpath=./ancestor::div[contains(@class, "card")]//div[contains(@class, "badge")]')).toHaveText(status); + } + + async verifyMyOrdersCount() { + await expect(this.page.locator(this.locators.myOrdersCount)).toBeVisible(); + } +} + +export default OrderPage; diff --git a/pages/ProductDetailsPage.js b/pages/ProductDetailsPage.js index 21ca8f2..3ab3379 100644 --- a/pages/ProductDetailsPage.js +++ b/pages/ProductDetailsPage.js @@ -1,63 +1,63 @@ -import BasePage from './BasePage.js'; -import { expect } from '@playwright/test'; - -class ProductDetailsPage extends BasePage{ - - /** - * @param {import('@playwright/test').Page} page - */ - constructor(page) { - super(page); - this.page = page; - } - - locators = { - plusIconToAddQuantity: '[aria-label="plus"]', - totalQuantity: '[aria-label="minus"] + div', - addToCartButton: 'ADD TO CART', - headerCartIcon: 'header-cart-icon' - } - - async assertProductNameTitle(productName) { - await expect(this.page.locator(`//h1[text()="${productName}"]`).first()).toBeVisible(); - } - - async assertProductReviewCount(productName, productReviewCount) { - await expect(this.page.locator(`//h1[text()="${productName}"]/following-sibling::div/p`).first()).toContainText(productReviewCount); - } - - async assertProductPrice(productName, productPrice) { - await expect(this.page.locator(`//h1[text()="${productName}"]/following-sibling::p[contains(@class, 'font-medium')]`).first()).toContainText(productPrice); - } - - getPlusIconToAddQuantity() { - return this.page.locator(this.locators.plusIconToAddQuantity) - } - - async clickPlusIconToAddQuantity() { - await this.getPlusIconToAddQuantity().click(); - } - - getTotalQuantity() { - return this.page.locator(this.locators.totalQuantity) - } - - getAddToCartButton() { - return this.page.getByText(this.locators.addToCartButton) - } - - async clickAddToCartButton() { - await this.getAddToCartButton().click(); - await expect(this.page.getByText('Added to the cart')).toBeVisible(); - } - - getCartIcon() { - return this.page.getByTestId(this.locators.headerCartIcon) - } - - async clickCartIcon() { - await this.getCartIcon().click(); - } -} - +import BasePage from './BasePage.js'; +import { expect } from '@playwright/test'; + +class ProductDetailsPage extends BasePage{ + + /** + * @param {import('@playwright/test').Page} page + */ + constructor(page) { + super(page); + this.page = page; + } + + locators = { + plusIconToAddQuantity: '[aria-label="plus"]', + totalQuantity: '[aria-label="minus"] + div', + addToCartButton: 'ADD TO CART', + headerCartIcon: 'header-cart-icon' + } + + async assertProductNameTitle(productName) { + await expect(this.page.locator(`//h1[text()="${productName}"]`).first()).toBeVisible(); + } + + async assertProductReviewCount(productName, productReviewCount) { + await expect(this.page.locator(`//h1[text()="${productName}"]/following-sibling::div/p`).first()).toContainText(productReviewCount); + } + + async assertProductPrice(productName, productPrice) { + await expect(this.page.locator(`//h1[text()="${productName}"]/following-sibling::p[contains(@class, 'font-medium')]`).first()).toContainText(productPrice); + } + + getPlusIconToAddQuantity() { + return this.page.locator(this.locators.plusIconToAddQuantity) + } + + async clickPlusIconToAddQuantity() { + await this.getPlusIconToAddQuantity().click(); + } + + getTotalQuantity() { + return this.page.locator(this.locators.totalQuantity) + } + + getAddToCartButton() { + return this.page.getByText(this.locators.addToCartButton) + } + + async clickAddToCartButton() { + await this.getAddToCartButton().click(); + await expect(this.page.getByText('Added to the cart')).toBeVisible(); + } + + getCartIcon() { + return this.page.getByTestId(this.locators.headerCartIcon) + } + + async clickCartIcon() { + await this.getCartIcon().click(); + } +} + export default ProductDetailsPage; \ No newline at end of file diff --git a/pages/SignupPage.js b/pages/SignupPage.js index 899b1d4..5e272ca 100644 --- a/pages/SignupPage.js +++ b/pages/SignupPage.js @@ -1,76 +1,76 @@ -import BasePage from './BasePage.js'; -import { expect } from '@playwright/test'; - -class SignupPage extends BasePage{ - - /** - * @param {import('@playwright/test').Page} page - */ - constructor(page) { - super(page); - this.page = page; - } - - locators = { - signupPageTitle: `//h2[text()=' Create Account']`, - firstName: `#firstname`, - lastName: `#lastname`, - email: `#email`, - password: `#password`, - signupButton: `//button[text()='Create Account']`, - successSignupMessage: `Account created successfully! Please login to continue.`, - } - - async navigateToSignupPage() { - await this.navigateTo('/signup'); - } - - getSignupPageTitle() { - return this.page.locator(this.locators.signupPageTitle); - } - - getFirstNameInput() { - return this.page.locator(this.locators.firstName); - } - - getLastNameInput() { - return this.page.locator(this.locators.lastName); - } - - getEmailInput() { - return this.page.locator(this.locators.email); - } - - getPasswordInput() { - return this.page.locator(this.locators.password); - } - - getSignupButton() { - return this.page.locator(this.locators.signupButton); - } - - - async assertSignupPage() { - await expect(this.getSignupPageTitle()).toBeVisible(); - await expect(this.getFirstNameInput()).toBeVisible(); - await expect(this.getLastNameInput()).toBeVisible(); - await expect(this.getEmailInput()).toBeVisible(); - await expect(this.getPasswordInput()).toBeVisible(); - await expect(this.getSignupButton()).toBeVisible(); - } - - async signup(firstName, lastName, email, password) { - await this.page.fill(this.locators.firstName, firstName); - await this.page.fill(this.locators.lastName, lastName); - await this.page.fill(this.locators.email, email); - await this.page.fill(this.locators.password, password); - await this.page.click(this.locators.signupButton); - await this.page.waitForTimeout(2000); - } - - async verifySuccessSignUp() { - await expect(this.page.getByText(this.locators.successSignupMessage)).toBeVisible({ timeout: 10000 }); - } -} - +import BasePage from './BasePage.js'; +import { expect } from '@playwright/test'; + +class SignupPage extends BasePage{ + + /** + * @param {import('@playwright/test').Page} page + */ + constructor(page) { + super(page); + this.page = page; + } + + locators = { + signupPageTitle: `//h2[text()=' Create Account']`, + firstName: `#firstname`, + lastName: `#lastname`, + email: `#email`, + password: `#password`, + signupButton: `//button[text()='Create Account']`, + successSignupMessage: `Account created successfully! Please login to continue.`, + } + + async navigateToSignupPage() { + await this.navigateTo('/signup'); + } + + getSignupPageTitle() { + return this.page.locator(this.locators.signupPageTitle); + } + + getFirstNameInput() { + return this.page.locator(this.locators.firstName); + } + + getLastNameInput() { + return this.page.locator(this.locators.lastName); + } + + getEmailInput() { + return this.page.locator(this.locators.email); + } + + getPasswordInput() { + return this.page.locator(this.locators.password); + } + + getSignupButton() { + return this.page.locator(this.locators.signupButton); + } + + + async assertSignupPage() { + await expect(this.getSignupPageTitle()).toBeVisible(); + await expect(this.getFirstNameInput()).toBeVisible(); + await expect(this.getLastNameInput()).toBeVisible(); + await expect(this.getEmailInput()).toBeVisible(); + await expect(this.getPasswordInput()).toBeVisible(); + await expect(this.getSignupButton()).toBeVisible(); + } + + async signup(firstName, lastName, email, password) { + await this.page.fill(this.locators.firstName, firstName); + await this.page.fill(this.locators.lastName, lastName); + await this.page.fill(this.locators.email, email); + await this.page.fill(this.locators.password, password); + await this.page.click(this.locators.signupButton); + await this.page.waitForTimeout(2000); + } + + async verifySuccessSignUp() { + await expect(this.page.getByText(this.locators.successSignupMessage)).toBeVisible({ timeout: 10000 }); + } +} + export default SignupPage; \ No newline at end of file diff --git a/pages/UserPage.js b/pages/UserPage.js index aa78c9a..f154d74 100644 --- a/pages/UserPage.js +++ b/pages/UserPage.js @@ -1,165 +1,165 @@ -// UserPage.js -import BasePage from './BasePage.js'; -import { expect } from '@playwright/test'; - -class UserPage extends BasePage { - /** - * @param {import('@playwright/test').Page} page - */ - constructor(page) { - super(page); - this.page = page; - } - - // Single source of truth for selectors (prefer data-testid where available) - locators = { - // Header / user menu - userIcon: `//*[name()='svg'][.//*[name()='path' and contains(@d,'M25.1578 1')]]`, - logoutButton: `//p[text()='Log Out']`, - - // Profile tabs & sections - addressTab: `(//*[@data-testid="menu-item-label"])[3]`, - addAddressButton: `[data-testid="add-new-address-button"]`, - addNewAddressMenu: `//h2[text()='Add New Address']`, - - // Address form (data-testid) - addressingFirstName: `[data-testid="first-name-input"]`, - addressingEmail: `[data-testid="email-input"]`, - streetAddress: `[data-testid="street-address-input"]`, - cityInput: `[data-testid="city-input"]`, - stateInput: `[data-testid="state-input"]`, - countryInput: `[data-testid="country-input"]`, - zipCodeInput: `[data-testid="zip-code-input"]`, - saveAddressButton: `[data-testid="save-address-button"]`, - - // Address cards list (generic selector for names) - addressCardName: `[data-testid="address-name"]`, - editAddressButton: `(//*[@data-icon='edit'])[1]`, - deleteAddressButton: `(//*[@data-icon='delete'])[1]`, - confirmDeleteButton: `//button[normalize-space(text())='Delete']`, - updateAddressButton: `//button[text()='Update']`, - - // Personal info section (profile form) - firstName: `[name="firstname"]`, - lastName: `[name="lastName"]`, - contactNumber: `[name="contactNumber"]`, - savePersonalInfo: `[aria-label="save"]`, - - // Security / password change - securityButton: `//button[text()="Security"]`, - enterNewPassword: `[placeholder="Enter new password"]`, - confirmNewPassword: `[placeholder="Confirm your password"]`, - updatePasswordButton: `[data-testid="my-profile-reset-password-button"]`, - updateNotification: `div[role="status"][aria-live="polite"]`, - }; - - /* ----------------------------- - * Generic helpers used in tests - * ----------------------------- */ - async clickOnUserProfileIcon() { - await this.page.locator(this.locators.userIcon).click(); - } - - /* ---------- Addresses ---------- */ - async clickOnAddressTab() { - await this.page.locator(this.locators.addressTab).click(); - } - - async clickOnAddAddressButton() { - await this.page.locator(this.locators.addAddressButton).click(); - } - - async checkAddNewAddressMenu() { - await expect(this.page.locator(this.locators.addNewAddressMenu)).toBeVisible(); - } - - async fillAddressForm() { - await this.page.locator(this.locators.addressingFirstName).fill('Tester'); - await this.page.locator(this.locators.addressingEmail).fill('testing123@example.com'); - await this.page.locator(this.locators.streetAddress).fill('SBP, Utran'); - await this.page.locator(this.locators.cityInput).fill('Surat'); - await this.page.locator(this.locators.stateInput).fill('Gujarat'); - await this.page.locator(this.locators.countryInput).fill('India'); - await this.page.locator(this.locators.zipCodeInput).fill('12345'); - await this.page.locator(this.locators.saveAddressButton).click(); - } - - async verifytheAddressIsAdded() { - // Assert at least one address card with the name we just saved is visible - const name = this.page.locator(this.locators.addressCardName); - await expect(name).toBeVisible(); - } - - async clickOnEditAddressButton() { - await this.page.locator(this.locators.editAddressButton).click(); - } - - async updateAddressForm() { - // Update to a new first name and keep other fields valid - await this.page.locator(this.locators.addressingFirstName).fill('Test1'); - await this.page.locator(this.locators.addressingEmail).fill('john.doe@example.com'); - await this.page.locator(this.locators.streetAddress).fill('123 Main St'); - await this.page.locator(this.locators.cityInput).fill('Anytown'); - await this.page.locator(this.locators.stateInput).fill('CA'); - await this.page.locator(this.locators.countryInput).fill('United States'); - await this.page.locator(this.locators.zipCodeInput).fill('12345'); - await this.page.locator(this.locators.updateAddressButton).click(); - } - - async verifytheUpdatedAddressIsAdded() { - await expect(this.page.locator(this.locators.addressCardName)).toContainText('Test1'); - } - - async clickOnDeleteAddressButton() { - // Ensure the address exists before deleting - await expect(this.page.locator(this.locators.addressCardName)).toContainText('Test1'); - await this.page.locator(this.locators.deleteAddressButton).click(); - await this.page.locator(this.locators.confirmDeleteButton).click(); - } - - /* ------- Personal Info -------- */ - async updatePersonalInfo() { - await this.page.locator(this.locators.firstName).fill('Test1'); - await this.page.locator(this.locators.lastName).fill('Testing'); - await this.page.locator(this.locators.contactNumber).fill('9999999999'); - await this.page.locator(this.locators.savePersonalInfo).click(); - } - - async verifyPersonalInfoUpdated() { - await this.page.reload(); - await expect(this.page.locator(this.locators.firstName)).toHaveValue('Test1'); - await expect(this.page.locator(this.locators.lastName)).toHaveValue('Testing'); - await expect(this.page.locator(this.locators.contactNumber)).toHaveValue('9999999999'); - } - - /* --------- Security (PW) ------ */ - async clickOnSecurityButton() { - await this.page.locator(this.locators.securityButton).click(); - } - - async enterNewPassword() { - await this.page.locator(this.locators.enterNewPassword).fill(process.env.NEW_PASSWORD); - } - - async enterConfirmNewPassword() { - await this.page.locator(this.locators.confirmNewPassword).fill(process.env.NEW_PASSWORD); - } - - async clickOnUpdatePasswordButton() { - await this.page.locator(this.locators.updatePasswordButton).click(); - } - - async revertPasswordBackToOriginal() { - await this.page.locator(this.locators.enterNewPassword).fill(process.env.PASSWORD); - await this.page.locator(this.locators.confirmNewPassword).fill(process.env.PASSWORD); - await this.page.locator(this.locators.updatePasswordButton).click(); - } - - async getUpdatePasswordNotification() { - const toast = this.page.locator(this.locators.updateNotification); - await expect(toast).toBeVisible(); - await expect(toast).toHaveText(/Password updated successfully/i); - } -} - -export default UserPage; +// UserPage.js +import BasePage from './BasePage.js'; +import { expect } from '@playwright/test'; + +class UserPage extends BasePage { + /** + * @param {import('@playwright/test').Page} page + */ + constructor(page) { + super(page); + this.page = page; + } + + // Single source of truth for selectors (prefer data-testid where available) + locators = { + // Header / user menu + userIcon: `//*[name()='svg'][.//*[name()='path' and contains(@d,'M25.1578 1')]]`, + logoutButton: `//p[text()='Log Out']`, + + // Profile tabs & sections + addressTab: `(//*[@data-testid="menu-item-label"])[3]`, + addAddressButton: `[data-testid="add-new-address-button"]`, + addNewAddressMenu: `//h2[text()='Add New Address']`, + + // Address form (data-testid) + addressingFirstName: `[data-testid="first-name-input"]`, + addressingEmail: `[data-testid="email-input"]`, + streetAddress: `[data-testid="street-address-input"]`, + cityInput: `[data-testid="city-input"]`, + stateInput: `[data-testid="state-input"]`, + countryInput: `[data-testid="country-input"]`, + zipCodeInput: `[data-testid="zip-code-input"]`, + saveAddressButton: `[data-testid="save-address-button"]`, + + // Address cards list (generic selector for names) + addressCardName: `[data-testid="address-name"]`, + editAddressButton: `(//*[@data-icon='edit'])[1]`, + deleteAddressButton: `(//*[@data-icon='delete'])[1]`, + confirmDeleteButton: `//button[normalize-space(text())='Delete']`, + updateAddressButton: `//button[text()='Update']`, + + // Personal info section (profile form) + firstName: `[name="firstname"]`, + lastName: `[name="lastName"]`, + contactNumber: `[name="contactNumber"]`, + savePersonalInfo: `[aria-label="save"]`, + + // Security / password change + securityButton: `//button[text()="Security"]`, + enterNewPassword: `[placeholder="Enter new password"]`, + confirmNewPassword: `[placeholder="Confirm your password"]`, + updatePasswordButton: `[data-testid="my-profile-reset-password-button"]`, + updateNotification: `div[role="status"][aria-live="polite"]`, + }; + + /* ----------------------------- + * Generic helpers used in tests + * ----------------------------- */ + async clickOnUserProfileIcon() { + await this.page.locator(this.locators.userIcon).click(); + } + + /* ---------- Addresses ---------- */ + async clickOnAddressTab() { + await this.page.locator(this.locators.addressTab).click(); + } + + async clickOnAddAddressButton() { + await this.page.locator(this.locators.addAddressButton).click(); + } + + async checkAddNewAddressMenu() { + await expect(this.page.locator(this.locators.addNewAddressMenu)).toBeVisible(); + } + + async fillAddressForm() { + await this.page.locator(this.locators.addressingFirstName).fill('Tester'); + await this.page.locator(this.locators.addressingEmail).fill('testing123@example.com'); + await this.page.locator(this.locators.streetAddress).fill('SBP, Utran'); + await this.page.locator(this.locators.cityInput).fill('Surat'); + await this.page.locator(this.locators.stateInput).fill('Gujarat'); + await this.page.locator(this.locators.countryInput).fill('India'); + await this.page.locator(this.locators.zipCodeInput).fill('12345'); + await this.page.locator(this.locators.saveAddressButton).click(); + } + + async verifytheAddressIsAdded() { + // Assert at least one address card with the name we just saved is visible + const name = this.page.locator(this.locators.addressCardName); + await expect(name).toBeVisible(); + } + + async clickOnEditAddressButton() { + await this.page.locator(this.locators.editAddressButton).click(); + } + + async updateAddressForm() { + // Update to a new first name and keep other fields valid + await this.page.locator(this.locators.addressingFirstName).fill('Test1'); + await this.page.locator(this.locators.addressingEmail).fill('john.doe@example.com'); + await this.page.locator(this.locators.streetAddress).fill('123 Main St'); + await this.page.locator(this.locators.cityInput).fill('Anytown'); + await this.page.locator(this.locators.stateInput).fill('CA'); + await this.page.locator(this.locators.countryInput).fill('United States'); + await this.page.locator(this.locators.zipCodeInput).fill('12345'); + await this.page.locator(this.locators.updateAddressButton).click(); + } + + async verifytheUpdatedAddressIsAdded() { + await expect(this.page.locator(this.locators.addressCardName)).toContainText('Test1'); + } + + async clickOnDeleteAddressButton() { + // Ensure the address exists before deleting + await expect(this.page.locator(this.locators.addressCardName)).toContainText('Test1'); + await this.page.locator(this.locators.deleteAddressButton).click(); + await this.page.locator(this.locators.confirmDeleteButton).click(); + } + + /* ------- Personal Info -------- */ + async updatePersonalInfo() { + await this.page.locator(this.locators.firstName).fill('Test1'); + await this.page.locator(this.locators.lastName).fill('Testing'); + await this.page.locator(this.locators.contactNumber).fill('9999999999'); + await this.page.locator(this.locators.savePersonalInfo).click(); + } + + async verifyPersonalInfoUpdated() { + await this.page.reload(); + await expect(this.page.locator(this.locators.firstName)).toHaveValue('Test1'); + await expect(this.page.locator(this.locators.lastName)).toHaveValue('Testing'); + await expect(this.page.locator(this.locators.contactNumber)).toHaveValue('9999999999'); + } + + /* --------- Security (PW) ------ */ + async clickOnSecurityButton() { + await this.page.locator(this.locators.securityButton).click(); + } + + async enterNewPassword() { + await this.page.locator(this.locators.enterNewPassword).fill(process.env.NEW_PASSWORD); + } + + async enterConfirmNewPassword() { + await this.page.locator(this.locators.confirmNewPassword).fill(process.env.NEW_PASSWORD); + } + + async clickOnUpdatePasswordButton() { + await this.page.locator(this.locators.updatePasswordButton).click(); + } + + async revertPasswordBackToOriginal() { + await this.page.locator(this.locators.enterNewPassword).fill(process.env.PASSWORD); + await this.page.locator(this.locators.confirmNewPassword).fill(process.env.PASSWORD); + await this.page.locator(this.locators.updatePasswordButton).click(); + } + + async getUpdatePasswordNotification() { + const toast = this.page.locator(this.locators.updateNotification); + await expect(toast).toBeVisible(); + await expect(toast).toHaveText(/Password updated successfully/i); + } +} + +export default UserPage; diff --git a/playwright.config.js b/playwright.config.js index 0d0990a..f6c3911 100644 --- a/playwright.config.js +++ b/playwright.config.js @@ -10,6 +10,7 @@ export default defineConfig({ retries: isCI ? 1 : 0, workers: isCI ? 1 : 1, + timeout: 60 * 1000, // ⏱️ each test fails after 1 min // In CI we only show a list reporter. The workflow sets --reporter=blob. // Locally you also get HTML and JSON. reporter: [ diff --git a/tests/example.spec.js b/tests/example.spec.js index 6e8f6d0..0aef386 100644 --- a/tests/example.spec.js +++ b/tests/example.spec.js @@ -267,3 +267,53 @@ test('Verify that a New User Can Successfully Complete the Journey from Registra await allPages.orderDetailsPage.assertOrderSummaryTotalValue(formattedSubtotal); await allPages.orderDetailsPage.clickBackToHomeButton(); }); +test('Verify that user add product to cart before logging in and then complete order after logging in', async () => { + await test.step('Navigate and add product to cart before logging in', async () => { + await allPages.homePage.clickOnShopNowButton(); + await allPages.homePage.clickProductImage(); + await allPages.homePage.clickAddToCartButton(); + await allPages.homePage.validateAddCartNotification(); + await allPages.loginPage.clickOnUserProfileIcon(); + }) + await test.step('Login and complete order', async () => { + await login(); + await allPages.cartPage.clickOnCartIcon(); + await allPages.cartPage.clickOnCheckoutButton(); + await allPages.checkoutPage.verifyCheckoutTitle(); + await allPages.checkoutPage.selectCashOnDelivery(); + await allPages.checkoutPage.verifyCashOnDeliverySelected(); + await allPages.checkoutPage.clickOnPlaceOrder(); + await allPages.checkoutPage.verifyOrderPlacedSuccessfully(); + })}); + test('Verify that user can filter products by price range', async () => { + await login(); + await allPages.homePage.clickOnShopNowButton(); + await allPages.homePage.clickOnFilterButton(); + await allPages.homePage.AdjustPriceRangeSlider('10000', '20000'); + await allPages.homePage.clickOnFilterButton(); + }) + test('Verify if user can add product to wishlist, moves it to card and then checks out', async () => { + await login(); + + await test.step('Add product to wishlistand then add to cart', async () => { + await allPages.homePage.clickOnShopNowButton(); + await allPages.inventoryPage.addToWishlist(); + await allPages.inventoryPage.assertWishlistIcon(); + await allPages.inventoryPage.clickOnWishlistIconHeader(); + await allPages.inventoryPage.assertWishlistPage(); + await allPages.inventoryPage.clickOnWishlistAddToCard(); + }) + + await test.step('Checkout product added to cart', async () => { + await allPages.cartPage.clickOnCartIcon(); + // await allPages.cartPage.verifyCartItemVisible('JBL Charge 4 Bluetooth Speaker'); + await allPages.cartPage.clickOnCheckoutButton(); + await allPages.checkoutPage.verifyCheckoutTitle(); + // await allPages.checkoutPage.verifyProductInCheckout('JBL Charge 4 Bluetooth Speaker'); + await allPages.checkoutPage.selectCashOnDelivery(); + await allPages.checkoutPage.verifyCashOnDeliverySelected(); + await allPages.checkoutPage.clickOnPlaceOrder(); + await allPages.checkoutPage.verifyOrderPlacedSuccessfully(); + }) + + }) \ No newline at end of file