From 19749b9bac15e6ef3a786884f5be0de738dc3ae4 Mon Sep 17 00:00:00 2001 From: najeeb1023 Date: Sat, 22 Jun 2024 14:54:29 +0200 Subject: [PATCH 1/8] getProductSizes --- package.json | 2 +- playwright.config.ts | 2 +- src/test/features/UserShopping.feature | 4 ++-- src/test/pages/UserShopping.ts | 15 ++++++++++++--- src/test/resources/userShoppingPage.json | 8 ++++++++ src/test/steps/userShopping.ts | 2 +- 6 files changed, 25 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index 2a05bac..4dd83d0 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "scripts": { "lunaapp": "cucumber-js --config=config/cucumber.js", "lunaapp:tags": "cucumber-js --config=config/cucumber.js --tags ", - "lunaapp:debug": "cucumber-js --config=config/cucumber.js --tags @debug" + "lunaapp:debug": "cucumber-js --config=config/cucumber.js --tags @MenShopping" }, "keywords": [], "author": "", diff --git a/playwright.config.ts b/playwright.config.ts index a970899..f391a4e 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -6,7 +6,7 @@ const logger = createCustomLogger(scenarioName); export const config: LaunchOptions = { timeout: 600000, - headless: true, + headless: false, // args:['--window-position=-1070,-100'], // customized for left-sided portrait monitor. slowMo: 300, logger: { diff --git a/src/test/features/UserShopping.feature b/src/test/features/UserShopping.feature index 1b470fc..1574d78 100644 --- a/src/test/features/UserShopping.feature +++ b/src/test/features/UserShopping.feature @@ -11,7 +11,7 @@ Feature: Verify that the user is able to purchase some item. Scenario: User shops for Men Jackets. When The user clicks on the "
" section and the user clicks on "" option. And The products are shown and user navigates to a product. - And The price of that product is shown. + And The price, size of that product is shown. Examples: | Section | Attire | @@ -21,7 +21,7 @@ Feature: Verify that the user is able to purchase some item. Scenario: User shops for Women Jackets. When The user clicks on the "
" section and the user clicks on "" option. And The products are shown and user navigates to a product. - And The price of that product is shown. + And The price, size of that product is shown. Examples: | Section | Attire | diff --git a/src/test/pages/UserShopping.ts b/src/test/pages/UserShopping.ts index 1853760..d2a6322 100644 --- a/src/test/pages/UserShopping.ts +++ b/src/test/pages/UserShopping.ts @@ -37,7 +37,9 @@ import { Page, expect } from "@playwright/test"; productShown:() => pageFixture.page.locator(getResource('productsShown').selectorValue), productPrice:() => pageFixture.page.locator(getResource('productPrice').selectorValue), shoppingList:() => pageFixture.page.locator(getResource('shoppingList').selectorValue), - productSize:() => pageFixture.page.locator(getResource('productSize').selectorValue) + productSize:() => pageFixture.page.locator(getResource('productSize').selectorValue), + getProductSize:() => pageFixture.page.locator(getResource('getProductSize').selectorValue), + getProductSizesAvailable:() => pageFixture.page.locator(getResource('getProductSizesAvailable').selectorValue) }; @@ -89,7 +91,14 @@ import { Page, expect } from "@playwright/test"; const regEx = /\$\d+\.\d{2}/; const matchPriceText = priceText.match(regEx); console.log("The price of the product -> "+matchPriceText[0]); - const text = (await this.menSectionLocators.productSize().textContent()).trim(); - console.log(text) + const sizeText = (await this.menSectionLocators.productSize().textContent()).trim(); + const getSizes = await this.menSectionLocators.getProductSizesAvailable().count(); + console.log(sizeText+'s' + ' available are: '); + for(let i=1;i<=getSizes;i++){ + const el = await pageFixture.page.locator(getResource('getProductSize').selectorValue.replace('FLAG', i.toString())).allTextContents(); + for (const text of el) { + console.log(''+i +")" + " " + text.trim()); + }; + } }; }; \ No newline at end of file diff --git a/src/test/resources/userShoppingPage.json b/src/test/resources/userShoppingPage.json index 6ff473c..e2bf022 100644 --- a/src/test/resources/userShoppingPage.json +++ b/src/test/resources/userShoppingPage.json @@ -33,6 +33,14 @@ { "elementName": "productSize", "selectorValue": "//div[contains(@class,'swatch-attribute size')]//span[contains(.,'Size')]" + }, + { + "elementName": "getProductSize", + "selectorValue": "//div[contains(@class,'swatch-option text')][FLAG]" + }, + { + "elementName": "getProductSizesAvailable", + "selectorValue": "//div[contains(@class,'swatch-option text')]" } ] } \ No newline at end of file diff --git a/src/test/steps/userShopping.ts b/src/test/steps/userShopping.ts index 56f161e..c19888d 100644 --- a/src/test/steps/userShopping.ts +++ b/src/test/steps/userShopping.ts @@ -14,6 +14,6 @@ When("The products are shown and user navigates to a product.", async function ( await categoryAndProductSectionFacade.selectRandomItem(); }); -When("The price of that product is shown.", async function (){ +When("The price, size of that product is shown.", async function (){ await userShopping.getProductPrice(); }); \ No newline at end of file From a839279d75bd1a4036a6484d8a7a6cc343a32f8d Mon Sep 17 00:00:00 2001 From: najeeb1023 Date: Sat, 22 Jun 2024 15:33:23 +0200 Subject: [PATCH 2/8] fix: logger fix, product details WIP. --- logger/logger.ts | 5 +++-- package.json | 6 +++--- playwright.config.ts | 7 +++---- src/test/hooks/hooks.ts | 9 ++++----- 4 files changed, 13 insertions(+), 14 deletions(-) diff --git a/logger/logger.ts b/logger/logger.ts index dba4ab6..7e3c5a5 100644 --- a/logger/logger.ts +++ b/logger/logger.ts @@ -3,7 +3,7 @@ import { allColors } from 'winston/lib/winston/config'; const { combine, timestamp, printf, colorize, splat } = format; -const createCustomLogger = (scenarioName: string) => { +const createCustomLogger = () => { const customFormat = printf(({ timestamp, level, message,}) => { return ` [${timestamp}] ${level} ${message}`; }); @@ -27,7 +27,8 @@ const createCustomLogger = (scenarioName: string) => { ) }), new transports.File({ - filename: `test-results/logs/${scenarioName}/log.log`, + filename: `test-results/logs/log.log`, + options: { flags: 'w' }, level: 'info', format: format.combine( timestamp({ diff --git a/package.json b/package.json index 4dd83d0..131bd89 100644 --- a/package.json +++ b/package.json @@ -3,9 +3,9 @@ "version": "1.0.0", "main": "index.js", "scripts": { - "lunaapp": "cucumber-js --config=config/cucumber.js", - "lunaapp:tags": "cucumber-js --config=config/cucumber.js --tags ", - "lunaapp:debug": "cucumber-js --config=config/cucumber.js --tags @MenShopping" + "cucumber:luma": "cucumber-js --config=config/cucumber.js", + "cucumber:luma:tags": "cucumber-js --config=config/cucumber.js --tags ", + "cucumber:luma:debug": "cucumber-js --config=config/cucumber.js --tags @MenShopping" }, "keywords": [], "author": "", diff --git a/playwright.config.ts b/playwright.config.ts index f391a4e..6843b24 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -1,13 +1,12 @@ import { LaunchOptions } from "@playwright/test"; import createCustomLogger from "./logger/logger"; -let scenarioName; -const logger = createCustomLogger(scenarioName); +const logger = createCustomLogger(); export const config: LaunchOptions = { timeout: 600000, - headless: false, - // args:['--window-position=-1070,-100'], // customized for left-sided portrait monitor. + headless: true, + // args:['--window-position=-1070,-100'], //* customized for left-sided portrait monitor. slowMo: 300, logger: { isEnabled: (name, severity) => name === 'api', diff --git a/src/test/hooks/hooks.ts b/src/test/hooks/hooks.ts index ff3293e..88ee293 100644 --- a/src/test/hooks/hooks.ts +++ b/src/test/hooks/hooks.ts @@ -8,17 +8,16 @@ let browser: Browser; let context: BrowserContext; BeforeAll(async function () { + pageFixture.logger = createCustomLogger(); + pageFixture.logger.info('----------------- New Test Run -----------------'); browser = await chromium.launch(config); }); -Before(async function ({ pickle }) { - const scenarioName = pickle.name + pickle.id; +Before(async function () { context = await browser.newContext({viewport: null}); const page = await context.newPage(); pageFixture.page = page; - pageFixture.logger = createCustomLogger(scenarioName) - - // pageFixture.logger = createLogger(options(scenarioName)); + // pageFixture.logger = createCustomLogger(); }); After(async function ({ pickle, result }) { From 1f46d2b952efad1f889768a9644902df817f2934 Mon Sep 17 00:00:00 2001 From: najeeb1023 Date: Sat, 22 Jun 2024 15:56:02 +0200 Subject: [PATCH 3/8] fix: logger fix, product details WIP. --- .github/workflows/playwright.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml index 6fc67e5..e60026a 100644 --- a/.github/workflows/playwright.yml +++ b/.github/workflows/playwright.yml @@ -18,7 +18,7 @@ jobs: - name: Install Playwright Browsers run: npx playwright install --with-deps - name: Cucumber-Tests - run: npm run lunaapp + run: cucumber:luma - uses: actions/upload-artifact@v4 if: always() with: From b3686cf4a9d92053508484002f01ad0a46920e81 Mon Sep 17 00:00:00 2001 From: najeeb1023 Date: Sat, 22 Jun 2024 15:57:53 +0200 Subject: [PATCH 4/8] fix: logger fix, product details WIP. --- .github/workflows/playwright.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml index e60026a..59599ea 100644 --- a/.github/workflows/playwright.yml +++ b/.github/workflows/playwright.yml @@ -18,7 +18,7 @@ jobs: - name: Install Playwright Browsers run: npx playwright install --with-deps - name: Cucumber-Tests - run: cucumber:luma + run: npm run cucumber:luma - uses: actions/upload-artifact@v4 if: always() with: From aac36281b42f594bef23af66a40bf92fcac8fc4d Mon Sep 17 00:00:00 2001 From: najeeb1023 Date: Sat, 22 Jun 2024 16:17:30 +0200 Subject: [PATCH 5/8] fix: added if else condition if product is not clicked successfully. --- src/test/pages/UserShopping.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/test/pages/UserShopping.ts b/src/test/pages/UserShopping.ts index d2a6322..62979a1 100644 --- a/src/test/pages/UserShopping.ts +++ b/src/test/pages/UserShopping.ts @@ -88,6 +88,8 @@ import { Page, expect } from "@playwright/test"; public async getProductPrice():Promise{ const priceText = (await this.menSectionLocators.productPrice().textContent()).trim(); + if(expect(await this.menSectionLocators.productPrice().isVisible)){ + pageFixture.logger.error('Product price is not visible, attempting to click product again.') const regEx = /\$\d+\.\d{2}/; const matchPriceText = priceText.match(regEx); console.log("The price of the product -> "+matchPriceText[0]); @@ -100,5 +102,8 @@ import { Page, expect } from "@playwright/test"; console.log(''+i +")" + " " + text.trim()); }; } + } else { + return this.selectRandomProduct(); + } }; }; \ No newline at end of file From 4d32014d397c3d53591c0d173e0fdc70191d4e61 Mon Sep 17 00:00:00 2001 From: najeeb1023 Date: Sat, 22 Jun 2024 16:41:35 +0200 Subject: [PATCH 6/8] fix: menSectionLocators -> userShoppingLocators --- src/test/features/UserShopping.feature | 2 +- src/test/pages/UserShopping.ts | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/test/features/UserShopping.feature b/src/test/features/UserShopping.feature index 1574d78..c505678 100644 --- a/src/test/features/UserShopping.feature +++ b/src/test/features/UserShopping.feature @@ -15,7 +15,7 @@ Feature: Verify that the user is able to purchase some item. Examples: | Section | Attire | - | Men | Tees | + | Men | Pants | @WomenShopping Scenario: User shops for Women Jackets. diff --git a/src/test/pages/UserShopping.ts b/src/test/pages/UserShopping.ts index 62979a1..c32b20c 100644 --- a/src/test/pages/UserShopping.ts +++ b/src/test/pages/UserShopping.ts @@ -29,7 +29,7 @@ import { Page, expect } from "@playwright/test"; pageFixture.page = page; }; - menSectionLocators = { + userShoppingLocators = { menSectionHeader:() => pageFixture.page.locator(getResource('menSectionBtn').selectorValue), attireSectionBtn:() => pageFixture.page.locator(getResource('attireSectionBtn').selectorValue), itemsShown:() => pageFixture.page.locator(getResource('itemsShown').selectorValue), @@ -53,7 +53,7 @@ import { Page, expect } from "@playwright/test"; }; public async showItems():Promise{ - const getNumberOfProducts = await this.menSectionLocators.productShown().count(); + const getNumberOfProducts = await this.userShoppingLocators.productShown().count(); process.stdout.write(' Products shown -> ' + getNumberOfProducts + '\n'); for(let i=1;i<=getNumberOfProducts;i++){ const getEl = await pageFixture.page.locator(getResource('itemsShown').selectorValue.replace('FLAG', i.toString())).allTextContents(); @@ -64,7 +64,7 @@ import { Page, expect } from "@playwright/test"; }; public async selectRandomProduct():Promise{ - const getNumberOfProducts = await this.menSectionLocators.productShown().count(); + const getNumberOfProducts = await this.userShoppingLocators.productShown().count(); let ind: number = Math.floor(Math.random() * getNumberOfProducts); if (ind == 0) { Math.floor(Math.random() * getNumberOfProducts); @@ -72,8 +72,8 @@ import { Page, expect } from "@playwright/test"; const el = (pageFixture.page.locator(getResource('itemsShown').selectorValue.replace('FLAG', `${ind}`))); await expect(el).toBeVisible(); await el.dblclick({force: true, timeout: 3000}); - const list = await this.menSectionLocators.shoppingList().isVisible(); - const listCount = await this.menSectionLocators.shoppingList().count(); + const list = await this.userShoppingLocators.shoppingList().isVisible(); + const listCount = await this.userShoppingLocators.shoppingList().count(); if (list == true){ pageFixture.logger.error('User not navigated, retrying click'); await pageFixture.page.waitForLoadState('networkidle'); @@ -87,14 +87,14 @@ import { Page, expect } from "@playwright/test"; }; public async getProductPrice():Promise{ - const priceText = (await this.menSectionLocators.productPrice().textContent()).trim(); - if(expect(await this.menSectionLocators.productPrice().isVisible)){ + const priceText = (await this.userShoppingLocators.productPrice().textContent()).trim(); + if(await this.userShoppingLocators.productPrice().isVisible){ pageFixture.logger.error('Product price is not visible, attempting to click product again.') const regEx = /\$\d+\.\d{2}/; const matchPriceText = priceText.match(regEx); console.log("The price of the product -> "+matchPriceText[0]); - const sizeText = (await this.menSectionLocators.productSize().textContent()).trim(); - const getSizes = await this.menSectionLocators.getProductSizesAvailable().count(); + const sizeText = (await this.userShoppingLocators.productSize().textContent()).trim(); + const getSizes = await this.userShoppingLocators.getProductSizesAvailable().count(); console.log(sizeText+'s' + ' available are: '); for(let i=1;i<=getSizes;i++){ const el = await pageFixture.page.locator(getResource('getProductSize').selectorValue.replace('FLAG', i.toString())).allTextContents(); From 5de0739923dde4781d730d72503c4d5afb7456e0 Mon Sep 17 00:00:00 2001 From: najeeb1023 Date: Sat, 22 Jun 2024 16:59:08 +0200 Subject: [PATCH 7/8] if condition isVisible() added. --- src/test/pages/UserShopping.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/pages/UserShopping.ts b/src/test/pages/UserShopping.ts index c32b20c..92bb345 100644 --- a/src/test/pages/UserShopping.ts +++ b/src/test/pages/UserShopping.ts @@ -88,7 +88,7 @@ import { Page, expect } from "@playwright/test"; public async getProductPrice():Promise{ const priceText = (await this.userShoppingLocators.productPrice().textContent()).trim(); - if(await this.userShoppingLocators.productPrice().isVisible){ + if(await this.userShoppingLocators.productPrice().isVisible() == true){ pageFixture.logger.error('Product price is not visible, attempting to click product again.') const regEx = /\$\d+\.\d{2}/; const matchPriceText = priceText.match(regEx); From 70541918f0e930ac26a10bed3d4a6331d1ca0bfb Mon Sep 17 00:00:00 2001 From: najeeb1023 Date: Sat, 22 Jun 2024 21:19:06 +0200 Subject: [PATCH 8/8] feat: selectAndGetProductColors function added. --- src/test/features/UserShopping.feature | 4 ++-- src/test/pages/UserShopping.ts | 24 +++++++++++++++++++++--- src/test/resources/userShoppingPage.json | 12 ++++++++++++ src/test/steps/userShopping.ts | 3 ++- 4 files changed, 37 insertions(+), 6 deletions(-) diff --git a/src/test/features/UserShopping.feature b/src/test/features/UserShopping.feature index c505678..768e02c 100644 --- a/src/test/features/UserShopping.feature +++ b/src/test/features/UserShopping.feature @@ -14,8 +14,8 @@ Feature: Verify that the user is able to purchase some item. And The price, size of that product is shown. Examples: - | Section | Attire | - | Men | Pants | + | Section | Attire | + | Men | Hoodies & Sweatshirts | @WomenShopping Scenario: User shops for Women Jackets. diff --git a/src/test/pages/UserShopping.ts b/src/test/pages/UserShopping.ts index 92bb345..667a12d 100644 --- a/src/test/pages/UserShopping.ts +++ b/src/test/pages/UserShopping.ts @@ -39,7 +39,9 @@ import { Page, expect } from "@playwright/test"; shoppingList:() => pageFixture.page.locator(getResource('shoppingList').selectorValue), productSize:() => pageFixture.page.locator(getResource('productSize').selectorValue), getProductSize:() => pageFixture.page.locator(getResource('getProductSize').selectorValue), - getProductSizesAvailable:() => pageFixture.page.locator(getResource('getProductSizesAvailable').selectorValue) + getProductSizesAvailable:() => pageFixture.page.locator(getResource('getProductSizesAvailable').selectorValue), + getCurrentSelectedColor:() => pageFixture.page.locator(getResource('getCurrentSelectedColor').selectorValue), + getColorSwatches:() => pageFixture.page.locator(getResource('getColorSwatches').selectorValue), }; @@ -65,7 +67,8 @@ import { Page, expect } from "@playwright/test"; public async selectRandomProduct():Promise{ const getNumberOfProducts = await this.userShoppingLocators.productShown().count(); - let ind: number = Math.floor(Math.random() * getNumberOfProducts); + let ind: number = Math.floor(Math.random() * (getNumberOfProducts - 1))+ 1; + if (ind == 0) { Math.floor(Math.random() * getNumberOfProducts); } else { @@ -86,7 +89,7 @@ import { Page, expect } from "@playwright/test"; }; }; - public async getProductPrice():Promise{ + public async getProductPriceAndSizes():Promise{ const priceText = (await this.userShoppingLocators.productPrice().textContent()).trim(); if(await this.userShoppingLocators.productPrice().isVisible() == true){ pageFixture.logger.error('Product price is not visible, attempting to click product again.') @@ -106,4 +109,19 @@ import { Page, expect } from "@playwright/test"; return this.selectRandomProduct(); } }; + + public async selectAndGetProductColors():Promise{ + const getColorSwatch = await this.userShoppingLocators.getColorSwatches().count(); + console.log('Color found: ' + getColorSwatch); + let ind: number = Math.floor(Math.random() * (getColorSwatch - 1)) + 1; + if (ind == 0) { + Math.floor(Math.random() * getColorSwatch); + } else { + const colorToBeSelect = await pageFixture.page.locator(getResource('colorSwatch').selectorValue.replace('FLAG', `${ind}`)); + await colorToBeSelect.click(); + await this.userShoppingLocators.getCurrentSelectedColor().isVisible(); + const getColor = await this.userShoppingLocators.getCurrentSelectedColor().textContent(); + console.log(getColor); + }; + }; }; \ No newline at end of file diff --git a/src/test/resources/userShoppingPage.json b/src/test/resources/userShoppingPage.json index e2bf022..832bea9 100644 --- a/src/test/resources/userShoppingPage.json +++ b/src/test/resources/userShoppingPage.json @@ -41,6 +41,18 @@ { "elementName": "getProductSizesAvailable", "selectorValue": "//div[contains(@class,'swatch-option text')]" + }, + { + "elementName": "getCurrentSelectedColor", + "selectorValue": "//div[contains(@class,'swatch-attribute color')]//span[2]" + }, + { + "elementName": "getColorSwatches", + "selectorValue": "//div[contains(@class,'swatch-option color')]" + }, + { + "elementName": "colorSwatch", + "selectorValue": "//div[contains(@class,'swatch-option color')][contains(@role,'option')][FLAG]" } ] } \ No newline at end of file diff --git a/src/test/steps/userShopping.ts b/src/test/steps/userShopping.ts index c19888d..a80014a 100644 --- a/src/test/steps/userShopping.ts +++ b/src/test/steps/userShopping.ts @@ -15,5 +15,6 @@ When("The products are shown and user navigates to a product.", async function ( }); When("The price, size of that product is shown.", async function (){ - await userShopping.getProductPrice(); + await userShopping.getProductPriceAndSizes(); + await userShopping.selectAndGetProductColors(); }); \ No newline at end of file