From f42a725adbb43ad5b90fdebf4ccfd930841b10dd Mon Sep 17 00:00:00 2001 From: Shay Date: Mon, 20 Jan 2025 12:12:47 +0100 Subject: [PATCH] Removed TODO comments (tickets created), remove empty tests, and add Gherkin description to a test --- bypass-captcha.config.example.ts | 1 - playwright.config.example.ts | 2 -- tests/base/account.spec.ts | 12 ---------- tests/base/cart.spec.ts | 2 -- tests/base/checkout.spec.ts | 24 +++++++++---------- tests/base/config/selectors/selectors.json | 5 +++- tests/base/fixtures/account.page.ts | 28 ++++------------------ tests/base/fixtures/checkout.page.ts | 3 --- tests/base/fixtures/login.page.ts | 4 ---- tests/base/fixtures/mainmenu.page.ts | 2 +- tests/base/fixtures/newsletter.page.ts | 2 -- tests/base/fixtures/product.page.ts | 1 - tests/base/home.spec.ts | 1 - tests/base/login.spec.ts | 25 ------------------- tests/base/mainmenu.spec.ts | 1 - tests/base/minicart.spec.ts | 2 -- tests/base/register.spec.ts | 23 ------------------ 17 files changed, 21 insertions(+), 117 deletions(-) diff --git a/bypass-captcha.config.example.ts b/bypass-captcha.config.example.ts index f9b0545..699cdeb 100644 --- a/bypass-captcha.config.example.ts +++ b/bypass-captcha.config.example.ts @@ -3,7 +3,6 @@ * It will set the global cookie to bypass CAPTCHA for Magento 2. * See: https://github.com/elgentos/magento2-bypass-captcha-cookie * - * //TODO The extension is WIP. Currently being developed. */ import { FullConfig } from '@playwright/test'; import * as playwright from 'playwright'; diff --git a/playwright.config.example.ts b/playwright.config.example.ts index 880e5e3..7760585 100644 --- a/playwright.config.example.ts +++ b/playwright.config.example.ts @@ -64,12 +64,10 @@ export default defineConfig({ /* Configure projects for major browsers */ projects: [ - // TODO: uncomment the setup line once authentication works! // Import our auth.setup.ts file //{ name: 'setup', testMatch: /.*\.setup\.ts/ }, { - // TODO: uncomment dependency and storage state once authentication works! name: 'chromium', testMatch: testFiles, use: { diff --git a/tests/base/account.spec.ts b/tests/base/account.spec.ts index a1ecf4b..ea5d14d 100644 --- a/tests/base/account.spec.ts +++ b/tests/base/account.spec.ts @@ -8,9 +8,6 @@ import inputvalues from './config/input-values/input-values.json'; import selectors from './config/selectors/selectors.json'; import verify from './config/expected/expected.json'; -// no resetting storageState, mainmenu has more functionalities when logged in. -// TODO: remove this beforeEach() once authentication as project set-up/fixture works. - // Before each test, log in test.beforeEach(async ({ page, browserName }) => { const browserEngine = browserName?.toUpperCase() || "UNKNOWN"; @@ -32,8 +29,6 @@ test.describe('Account information actions', {annotation: {type: 'Account Dashbo await page.waitForLoadState(); }); - // TODO: add test to update e-mail address - /** * @feature Magento 2 Change Password * @scenario User changes their password @@ -46,8 +41,6 @@ test.describe('Account information actions', {annotation: {type: 'Account Dashbo * @then I should see a notification that my password has been updated * @and I should be able to login with my new credentials. */ - - //TODO: Remove the skip when all issues are fixed. test.skip('I can change my password',{ tag: '@account-credentials', }, async ({page}) => { const accountPage = new AccountPage(page); let changedPasswordValue = process.env.MAGENTO_EXISTING_ACCOUNT_CHANGED_PASSWORD; @@ -68,8 +61,6 @@ test.describe('Account information actions', {annotation: {type: 'Account Dashbo }); -// TODO: Add tests to check address can't be added/updated if the supplied information is incorrect -// TODO: Add tests to check address can't be deleted if it's the last/only one. test.describe('Account address book actions', { annotation: {type: 'Account Dashboard', description: 'Tests for the Address Book'},}, () => { test.beforeEach(async ({page}) => { // go to the Adress Book page @@ -181,15 +172,12 @@ test.describe('Account address book actions', { annotation: {type: 'Account Dash }); }); -// TODO: move this to new spec file. test.describe('Newsletter actions', { annotation: {type: 'Account Dashboard', description: 'Newsletter tests'},}, () => { test.beforeEach(async ({page}) => { // go to the Dashboard page await page.goto(slugs.account.accountOverviewSlug); }); - // TODO: What if website offers multiple subscriptions? - /** * @feature Magento 2 newsletter subscriptions * @scenario User (un)subscribes from a newsletter diff --git a/tests/base/cart.spec.ts b/tests/base/cart.spec.ts index 5022ca2..84f5163 100644 --- a/tests/base/cart.spec.ts +++ b/tests/base/cart.spec.ts @@ -24,7 +24,6 @@ test.describe('Cart functionalities (guest)', () => { const mainMenu = new MainMenuPage(page); const productPage = new ProductPage(page); - //TODO: Use a storagestate or API call to add product to the cart so shorten test time await page.goto(slugs.productpage.simpleProductSlug); await productPage.addSimpleProductToCart(selectors.productPage.simpleProductTitle, slugs.productpage.simpleProductSlug); await mainMenu.openMiniCart(); @@ -127,7 +126,6 @@ test.describe('Cart functionalities (guest)', () => { throw new Error(`MAGENTO_COUPON_CODE_${browserEngine} appears to not be set in .env file. Value reported: ${discountCode}`); } - // TODO: create API call to quickly add discount code rather than run a test again. await cart.applyDiscountCode(discountCode); await cart.removeDiscountCode(); }); diff --git a/tests/base/checkout.spec.ts b/tests/base/checkout.spec.ts index 3589312..f53d661 100644 --- a/tests/base/checkout.spec.ts +++ b/tests/base/checkout.spec.ts @@ -9,8 +9,6 @@ import selectors from './config/selectors/selectors.json'; import verify from './config/expected/expected.json'; import { CheckoutPage } from './fixtures/checkout.page'; -// no resetting storageState, mainmenu has more functionalities when logged in. - /** * @feature BeforeEach runs before each test in this group. * @scenario Add product to the cart, confirm it's there, then move to checkout. @@ -25,7 +23,6 @@ import { CheckoutPage } from './fixtures/checkout.page'; test.beforeEach(async ({ page }) => { const productPage = new ProductPage(page); - //TODO: Use a storagestate or API call to add product to the cart so shorten test time await page.goto(slugs.productpage.simpleProductSlug); await productPage.addSimpleProductToCart(selectors.productPage.simpleProductTitle, slugs.productpage.simpleProductSlug); await page.goto(slugs.checkoutSlug); @@ -34,7 +31,6 @@ test.beforeEach(async ({ page }) => { test.describe('Checkout (login required)', () => { // Before each test, log in - // TODO: remove this beforeEach() once authentication as project set-up/fixture works. test.beforeEach(async ({ page, browserName }) => { const browserEngine = browserName?.toUpperCase() || "UNKNOWN"; let emailInputValue = process.env[`MAGENTO_EXISTING_ACCOUNT_EMAIL_${browserEngine}`]; @@ -48,20 +44,26 @@ test.describe('Checkout (login required)', () => { await loginPage.login(emailInputValue, passwordInputValue); }); - //TODO: Add Gherkin feature description + + /** + * @feature Place order for simple product + * @scenario User places an order for a simple product + * @given I have a product in my cart + * @and I am on any page + * @when I navigate to the checkout + * @and I fill in the required fields + * @and I click the button to place my order + * @then I should see a confirmation that my order has been placed + * @and a order number should be created and show to me + */ test('Place order for simple product',{ tag: '@simple-product-order',}, async ({page}) => { const checkoutPage = new CheckoutPage(page); await checkoutPage.placeOrder(); }); - - }); test.describe('Checkout (guest)', () => { - // TODO: Write test to confirm order can be placed without an account - // TODO: Write test for logged-in user who hasn't added an address yet. - /** * @feature Discount Code * @scenario User adds a discount code to their cart @@ -75,7 +77,6 @@ test.describe('Checkout (guest)', () => { * @and a discount should be applied to the product */ test('Add coupon code in checkout',{ tag: ['@checkout', '@coupon-code']}, async ({page, browserName}) => { - //TODO: Write tests to ensure code also works if user is NOT logged in. const checkout = new CheckoutPage(page); const browserEngine = browserName?.toUpperCase() || "UNKNOWN"; let discountCode = process.env[`MAGENTO_COUPON_CODE_${browserEngine}`]; @@ -110,7 +111,6 @@ test.describe('Checkout (guest)', () => { throw new Error(`MAGENTO_COUPON_CODE appears to not be set in .env file. Value reported: ${discountCode}`); } - // TODO: create API call to quickly add discount code rather than run a test again. await checkout.applyDiscountCodeCheckout(discountCode); await checkout.removeDiscountCode(); }); diff --git a/tests/base/config/selectors/selectors.json b/tests/base/config/selectors/selectors.json index 04b3a8a..b3a684e 100644 --- a/tests/base/config/selectors/selectors.json +++ b/tests/base/config/selectors/selectors.json @@ -16,8 +16,11 @@ "nameFieldLabel": "Name", "emailFieldLabel": "Email", "passwordFieldLabel": "Password", + "newPasswordFieldLabel": "New Password", "passwordConfirmFieldLabel": "Confirm Password", - "loginButtonLabel": "Sign In" + "newPasswordConfirmFieldLabel": "Confirm New Password", + "loginButtonLabel": "Sign In", + "currentPasswordFieldLabel": "Current Password" }, "personalInformation": { "firstNameLabel": "First Name", diff --git a/tests/base/fixtures/account.page.ts b/tests/base/fixtures/account.page.ts index 69aabd9..9a16e8e 100644 --- a/tests/base/fixtures/account.page.ts +++ b/tests/base/fixtures/account.page.ts @@ -31,14 +31,6 @@ export class AccountPage { readonly accountCreationPasswordRepeatField: Locator; readonly accountCreationConfirmButton: Locator; - // fields below are not required when adding an address. - /* - readonly companyField: Locator; - readonly streetAddressFieldTwo: Locator; - readonly streetAddressFieldThree: Locator; - */ - - // TODO: Update these functionalities to be able to take in non-required fields. constructor(page: Page){ this.page = page; @@ -49,20 +41,15 @@ export class AccountPage { this.streetAddressField = page.getByLabel(selectors.newAddress.streetAddressLabel, {exact:true}); this.zipCodeField = page.getByLabel(selectors.newAddress.zipCodeLabel); this.cityField = page.getByLabel(selectors.newAddress.cityNameLabel); - //TODO: countrySelect is used to change the country so it's not US. - //TODO: provinceSelect should be provinceField if country is, for example, Netherlands. this.countrySelectorField = page.getByLabel(selectors.newAddress.countryLabel); this.stateSelectorField = page.getByLabel(selectors.newAddress.provinceSelectLabel).filter({hasText: selectors.newAddress.provinceSelectFilterLabel}); this.saveAddressButton = page.getByRole('button',{name: selectors.newAddress.saveAdressButton}); - //unrequired fields - // this.companyField = page.getByLabel(selectors.newAddress.companyNameLabel); // Account Information elements this.changePasswordCheck = page.getByRole('checkbox', {name: selectors.personalInformation.changePasswordCheckLabel}); - //TODO: Fix these once I can log in again - this.currentPasswordField = page.getByLabel('Current Password'); - this.newPasswordField = page.getByLabel('New Password', {exact:true}); - this.confirmNewPasswordField = page.getByLabel('Confirm New Password') + this.currentPasswordField = page.getByLabel(selectors.credentials.currentPasswordFieldLabel); + this.newPasswordField = page.getByLabel(selectors.credentials.newPasswordFieldLabel, {exact:true}); + this.confirmNewPasswordField = page.getByLabel(selectors.credentials.newPasswordConfirmFieldLabel); this.genericSaveButton = page.getByRole('button', { name: selectors.general.genericSaveButtonLabel }); // Account Creation elements @@ -79,11 +66,9 @@ export class AccountPage { this.editAddressButton = page.getByRole('link', {name: selectors.accountDashboard.editAddressIconButton}).first(); } - //TODO: Add ability to choose different country other than US async addNewAddress(phonenumber: string,streetName: string, zipCode: string, cityName: string, state: string){ let addressAddedNotification = verify.address.newAddressAddedNotifcation; - // Name should be filled in automatically. await expect(this.firstNameField).not.toBeEmpty(); await expect(this.lastNameField).not.toBeEmpty(); @@ -104,7 +89,6 @@ export class AccountPage { // the notification for a modified address is the same as the notification for a new address. let addressModifiedNotification = verify.address.newAddressAddedNotifcation; - // .click() replaced by .press("Enter") as a workaround for webkit issues await this.editAddressButton.click(); // Name should be filled in automatically, but editable. @@ -117,7 +101,7 @@ export class AccountPage { await this.zipCodeField.fill(zipCode); await this.cityField.fill(cityName); await this.stateSelectorField.selectOption(state); - // .click() replaced by .press("Enter") as a workaround for webkit issues + await this.saveAddressButton.click(); await this.page.waitForLoadState(); @@ -126,8 +110,6 @@ export class AccountPage { } - // TODO: Update function to remove random address from address book? - // deleteAddressButton is currently the first instance it finds. async deleteFirstAddressFromAddressBook(){ let addressDeletedNotification = verify.address.addressDeletedNotification; // Dialog function to click confirm @@ -137,7 +119,6 @@ export class AccountPage { } }); - // .click() replaced by .press("Enter") as a workaround for webkit issues await this.deleteAddressButton.click(); await this.page.waitForLoadState(); await expect(this.page.getByText(addressDeletedNotification)).toBeVisible(); @@ -151,7 +132,6 @@ export class AccountPage { await this.newPasswordField.fill(newPassword); await this.confirmNewPasswordField.fill(newPassword); - // .click() replaced by .press("Enter") as a workaround for webkit issues await this.genericSaveButton.click(); await this.page.waitForLoadState(); diff --git a/tests/base/fixtures/checkout.page.ts b/tests/base/fixtures/checkout.page.ts index ce1cab1..bafebb8 100644 --- a/tests/base/fixtures/checkout.page.ts +++ b/tests/base/fixtures/checkout.page.ts @@ -6,7 +6,6 @@ import slugs from '../config/slugs.json'; export class CheckoutPage { - //TODO: Expand with fields for when user is not logged in or has not provided an address readonly page: Page; readonly shippingMethodOptionFixed: Locator; readonly paymentMethodOptionCheck: Locator; @@ -53,8 +52,6 @@ export class CheckoutPage { let orderNumber = await this.page.locator('p').filter({ hasText: 'Your order number is:' }).getByRole('link').innerText(); console.log(`Your ordernumer is: ${orderNumber}`); - // This await only exists to report order number to the HTML reporter. - // TODO: replace this with a proper way to write something to the HTML reporter. await expect(this.continueShoppingButton, `Your order number is: ${orderNumber}`).toBeVisible(); return orderNumber; } diff --git a/tests/base/fixtures/login.page.ts b/tests/base/fixtures/login.page.ts index d1bdcf2..0f0ffe2 100644 --- a/tests/base/fixtures/login.page.ts +++ b/tests/base/fixtures/login.page.ts @@ -17,8 +17,6 @@ export class LoginPage { this.loginButton = page.getByRole('button', { name: selectors.credentials.loginButtonLabel }); } - // Note: this login function is simply written to quickly log in for tests which require you to be logged in. - // TODO: this login function should be moved to an auth file. see login.spec.ts line 15 and 16 for more info. async login(email: string, password: string){ await this.page.goto(slugs.account.loginSlug); await this.loginEmailField.fill(email); @@ -26,8 +24,6 @@ export class LoginPage { // usage of .press("Enter") to prevent webkit issues with button.click(); await this.loginButton.press("Enter"); - // this element cannot be defined in the constructor, since the sign out button only appears after logging in. - // Using a selector rather than expected, since it's we're locating a button rather than an expected notification. await expect(this.page.getByRole('link', { name: selectors.mainMenu.myAccountLogoutItem })).toBeVisible(); } } \ No newline at end of file diff --git a/tests/base/fixtures/mainmenu.page.ts b/tests/base/fixtures/mainmenu.page.ts index 85b0f74..475e005 100644 --- a/tests/base/fixtures/mainmenu.page.ts +++ b/tests/base/fixtures/mainmenu.page.ts @@ -29,7 +29,7 @@ export class MainMenuPage { } async gotoAddressBook() { - // TODO: create function to navigate to Address Book through the header menu links + // create function to navigate to Address Book through the header menu links } async openMiniCart() { diff --git a/tests/base/fixtures/newsletter.page.ts b/tests/base/fixtures/newsletter.page.ts index bcf8d04..55d310b 100644 --- a/tests/base/fixtures/newsletter.page.ts +++ b/tests/base/fixtures/newsletter.page.ts @@ -13,8 +13,6 @@ export class NewsletterSubscriptionPage { this.saveSubscriptionsButton = page.getByRole('button', {name:selectors.newsletterSubscriptions.saveSubscriptionsButton}); } - //TODO: the text of the notification can differ sometimes. Update this function to take this into account. - // newsletterRemovedNotification should sometimes be newsletterUpdatedNotification. async updateNewsletterSubscription(){ if(await this.newsletterCheckElement.isChecked()) { diff --git a/tests/base/fixtures/product.page.ts b/tests/base/fixtures/product.page.ts index 8d5e108..bf16337 100644 --- a/tests/base/fixtures/product.page.ts +++ b/tests/base/fixtures/product.page.ts @@ -42,6 +42,5 @@ export class ProductPage { await this.simpleProductAddToCartButon.click(); await this.page.waitForLoadState(); - //TODO: add notification check to ensure product has been added. } } \ No newline at end of file diff --git a/tests/base/home.spec.ts b/tests/base/home.spec.ts index e0ec114..a256146 100644 --- a/tests/base/home.spec.ts +++ b/tests/base/home.spec.ts @@ -8,7 +8,6 @@ test('Add product on homepage to cart',{ tag: '@homepage',}, async ({page}) => { const homepage = new HomePage(page); const mainmenu = new MainMenuPage(page); - // TODO: rework adding product to cart into API call function to reduce test time await page.goto(''); await homepage.addHomepageProductToCart(); await mainmenu.openMiniCart(); diff --git a/tests/base/login.spec.ts b/tests/base/login.spec.ts index 15e9a1a..e990163 100644 --- a/tests/base/login.spec.ts +++ b/tests/base/login.spec.ts @@ -1,24 +1,6 @@ import {test as base} from '@playwright/test'; import {LoginPage} from './fixtures/login.page'; -/* -const test = base.extend<{ loginPage:LoginPage }>({ - loginPage: async ({ page }, use) => { - const loginPage = new LoginPage(page); - await loginPage.login(); - } -}); -*/ - -//TODO: create an auth.setup.ts file to handle authentication (see login function on login.page.ts) -//TODO: link that setup file in project dependencies to be logged for all tests. -// See: https://playwright.dev/docs/auth#basic-shared-account-in-all-tests - -//TODO: login.spec.ts can be removed when storageState functionality has been implemented. Relevant functions should be moved to mainmenu, footer, search, or other page spec files. - -// Reset storageState to ensure we're not logged in before running these tests. -base.use({ storageState: { cookies: [], origins: [] } }); - base('User can log in with valid credentials', async ({page, browserName}) => { const browserEngine = browserName?.toUpperCase() || "UNKNOWN"; let emailInputValue = process.env[`MAGENTO_EXISTING_ACCOUNT_EMAIL_${browserEngine}`]; @@ -31,10 +13,3 @@ base('User can log in with valid credentials', async ({page, browserName}) => { const loginPage = new LoginPage(page); await loginPage.login(emailInputValue, passwordInputValue); }); - -//TODO: Add test to ensure user cannot log in with invalid credentials. -// Basically, we log in with wrong credentials, then expect a failure message. -// These tests should have a specific "error checker" tag. - - -//TODO: Add test to test 'Forgot your Password' functionality diff --git a/tests/base/mainmenu.spec.ts b/tests/base/mainmenu.spec.ts index 86b521c..c2e4e1a 100644 --- a/tests/base/mainmenu.spec.ts +++ b/tests/base/mainmenu.spec.ts @@ -4,7 +4,6 @@ import {MainMenuPage} from './fixtures/mainmenu.page'; // no resetting storageState, mainmenu has more functionalities when logged in. -// TODO: remove this beforeEach() once authentication as project set-up/fixture works. // Before each test, log in test.beforeEach(async ({ page, browserName }) => { const browserEngine = browserName?.toUpperCase() || "UNKNOWN"; diff --git a/tests/base/minicart.spec.ts b/tests/base/minicart.spec.ts index 42066b0..8309d45 100644 --- a/tests/base/minicart.spec.ts +++ b/tests/base/minicart.spec.ts @@ -25,7 +25,6 @@ test.describe('Minicart Actions', {annotation: {type: 'Minicart', description: ' const mainMenu = new MainMenuPage(page); const productPage = new ProductPage(page); - //TODO: Use a storagestate or API call to add product to the cart so shorten test time await page.goto(slugs.productpage.simpleProductSlug); await productPage.addSimpleProductToCart(selectors.productPage.simpleProductTitle, slugs.productpage.simpleProductSlug); await mainMenu.openMiniCart(); @@ -115,7 +114,6 @@ test.describe('Minicart Actions', {annotation: {type: 'Minicart', description: ' const mainMenu = new MainMenuPage(page); const productPage = new ProductPage(page); - //TODO: Use a storagestate or API call to add product to the cart so shorten test time await page.goto(slugs.productpage.configurableProductSlug); await productPage.addConfigurableProductToCart(); await mainMenu.openMiniCart(); diff --git a/tests/base/register.spec.ts b/tests/base/register.spec.ts index 23e1021..9b643b5 100644 --- a/tests/base/register.spec.ts +++ b/tests/base/register.spec.ts @@ -16,29 +16,13 @@ test.use({ storageState: { cookies: [], origins: [] } }); * @then I should see a messsage confirming my account was created */ test('User can register an account', { tag: '@setup', }, async ({page, browserName}) => { -// TODO: remove the 'skip' when done. We don't always want to create accounts. const registerPage = new RegisterPage(page); // Retrieve desired password from .env file const existingAccountPassword = process.env.MAGENTO_EXISTING_ACCOUNT_PASSWORD; var firstName = inputvalues.accountCreation.firstNameValue; var lastName = inputvalues.accountCreation.lastNameValue; - - - // TODO: Once setup script works, uncomment this section (uniqueEmailSection) and remove the one below - //Create unique email with custom handle and host, adding a number between 0 - 100 - /* let randomNumber = Math.floor(Math.random() * 100); - let emailHandle = inputvalues.accountCreation.emailHandleValue; - let emailHost = inputvalues.accountCreation.emailHostValue; - const uniqueEmail = `${emailHandle}${randomNumber}@${emailHost}`; - - if(!existingAccountPassword){ - throw new Error("MAGENTO_EXISTING_ACCOUNT_PASSWORD has not been defined in the .env file."); - } */ - // end of uniqueEmailSection - - //TODO: Once setup script works, remove this section (browserNameEmailSection) and use uniqueEmail from above const browserEngine = browserName?.toUpperCase() || "UNKNOWN"; let randomNumber = Math.floor(Math.random() * 100); let emailHandle = inputvalues.accountCreation.emailHandleValue; @@ -57,10 +41,3 @@ test('User can register an account', { tag: '@setup', }, async ({page, browserNa // password is retrieved from .env file in createNewAccount() function await registerPage.createNewAccount(firstName, lastName, accountEmail, existingAccountPassword); }); - - -test.skip('Account creation fails if required fields are not filled in', { tag: '@error-checker', }, async ({page}) => { - // TODO: registration should not work if mistakes are made, and proper messages should be displayed. - // These tests should have a specific "error checker" tag. - test.fixme(true,'Skipped, test will be created later'); -});