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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion features/login.feature
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ Feature: Login Feature

Scenario: Validate the login page title
# TODO: Fix this failing scenario
Then I should see the title "Labs Swag"
Then I should see the title "Swag Labs"

Scenario: Validate login error message
Then I will login as 'locked_out_user'
And Validate error message as 'Epic sadface: Sorry, this user has been locked out.'
# TODO: Add a step to validate the error message received
9 changes: 8 additions & 1 deletion features/product.feature
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,15 @@ Feature: Product Feature
# Create a datatable to validate the Price (high to low) and Price (low to high) sort options (top-right) using a Scenario Outline
Scenario Outline: Validate product sort by price <sort>
Then I will login as 'standard_user'
Then I sort the items by "<sort>"
Then I validate all 6 items are sorted correctly by price "<sort>"

# TODO: Sort the items by <sort>
# TODO: Validate all 6 items are sorted correctly by price
Examples:
# TODO: extend the datatable to paramterize this test
| sort |
| sort |
| Price (low to high) |
| Price (high to low) |


8 changes: 8 additions & 0 deletions features/purchase.feature
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ Feature: Purchase Feature
Scenario: Validate successful purchase text
Then I will login as 'standard_user'
Then I will add the backpack to the cart
Then I select the cart from top right
Then I select Checkout
Then I fill in First Name "Vibin", Last Name "Thomas", and ZipCode "99470"
Then I select Continue
Then I select Finish
Then I should see the purchase confirmation "Thank you for your order!"


# TODO: Select the cart (top-right)
# TODO: Select Checkout
# TODO: Fill in the First Name, Last Name, and Zip/Postal Code
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 8 additions & 1 deletion pages/login.page.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { Page } from "@playwright/test"
import { Page, expect } from "@playwright/test"

export class Login {
private readonly page: Page
private readonly password: string = 'secret_sauce'
private readonly passwordField: string = 'input[id="password"]'
private readonly userNameField: string = 'input[id="user-name"]'
private readonly loginButton: string = 'input[id="login-button"]'
private readonly errorMessageLocator: string = 'h3[data-test="error"]'

constructor(page: Page) {
this.page = page;
Expand All @@ -23,4 +24,10 @@ export class Login {
await this.page.locator(this.passwordField).fill(this.password)
await this.page.locator(this.loginButton).click()
}

public async validateErrorMessage(expectedMessage: string) {
const errorLocator = this.page.locator(this.errorMessageLocator);
await expect(errorLocator).toHaveText(expectedMessage);
}

}
21 changes: 20 additions & 1 deletion pages/product.page.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import { Page } from "@playwright/test"
import { Page, expect } from "@playwright/test"

export class Product {
private readonly page: Page
private readonly addToCart: string = 'button[id="add-to-cart-sauce-labs-backpack"]'
private readonly sortDropdown = 'select[data-test="product-sort-container"]';
private readonly itemPrices = '.inventory_item_price';


constructor(page: Page) {
this.page = page;
Expand All @@ -11,4 +14,20 @@ export class Product {
public async addBackPackToCart() {
await this.page.locator(this.addToCart).click()
}
public async sortItems(sortOption: string) {
await this.page.selectOption(this.sortDropdown, { label: sortOption });
}
public async validateSortedByPrice(sortOption: string) {
const prices = await this.page.$$eval(this.itemPrices, els =>
els.map(el => parseFloat(el.textContent!.replace('$', '')))
);

const sortedPrices = [...prices].sort((a, b) =>
sortOption.includes('low to high') ? a - b : b - a
);

expect(prices).toEqual(sortedPrices);
expect(prices.length).toBe(6); // ensure 6 items
}

}
50 changes: 50 additions & 0 deletions pages/purchase.page.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { Page, expect } from '@playwright/test';

export class Purchase {
private readonly page: Page;

private readonly backpackAddButton = 'button[id="add-to-cart-sauce-labs-backpack"]';
private readonly cartIcon = 'a.shopping_cart_link';
private readonly checkoutButton = 'button[id="checkout"]';
private readonly firstNameField = 'input[id="first-name"]';
private readonly lastNameField = 'input[id="last-name"]';
private readonly zipField = 'input[id="postal-code"]';
private readonly continueButton = 'input[id="continue"]';
private readonly finishButton = 'button[id="finish"]';
private readonly confirmationText = 'h2[class="complete-header"]';

constructor(page: Page) {
this.page = page;
}

public async addBackpack() {
await this.page.click(this.backpackAddButton);
}

public async openCart() {
await this.page.click(this.cartIcon);
}

public async checkout() {
await this.page.click(this.checkoutButton);
}

public async fillCheckoutInfo(firstName: string, lastName: string, zip: string) {
await this.page.fill(this.firstNameField, firstName);
await this.page.fill(this.lastNameField, lastName);
await this.page.fill(this.zipField, zip);
}

public async continueCheckout() {
await this.page.click(this.continueButton);
}

public async finishCheckout() {
await this.page.click(this.finishButton);
}

public async validateConfirmation(expectedText: string) {
const confirmation = this.page.locator(this.confirmationText);
await expect(confirmation).toHaveText(expectedText);
}
}
9 changes: 8 additions & 1 deletion steps/login.steps.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Then } from '@cucumber/cucumber';
import { getPage } from '../playwrightUtilities';
import { expect } from '@playwright/test';
import { Login } from '../pages/login.page';

Then('I should see the title {string}', async (expectedTitle) => {
Expand All @@ -8,4 +9,10 @@ Then('I should see the title {string}', async (expectedTitle) => {

Then('I will login as {string}', async (userName) => {
await new Login(getPage()).loginAsUser(userName);
});
});

Then('Validate error message as {string}', async (expectedMessage) => {
await new Login(getPage()).validateErrorMessage(expectedMessage);
});


10 changes: 9 additions & 1 deletion steps/product.steps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,12 @@ import { Product } from '../pages/product.page';

Then('I will add the backpack to the cart', async () => {
await new Product(getPage()).addBackPackToCart();
});
});

Then('I sort the items by {string}', async (sortOption: string) => {
await new Product(getPage()).sortItems(sortOption);
});

Then('I validate all 6 items are sorted correctly by price {string}', async (sortOption: string) => {
await new Product(getPage()).validateSortedByPrice(sortOption);
});
30 changes: 30 additions & 0 deletions steps/purchase.steps.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { Then } from '@cucumber/cucumber';
import { getPage } from '../playwrightUtilities';
import { Purchase } from '../pages/purchase.page';

Then('I select the cart from top right', async () => {
await new Purchase(getPage()).openCart();
});

Then('I select Checkout', async () => {
await new Purchase(getPage()).checkout();
});

Then(
'I fill in First Name {string}, Last Name {string}, and ZipCode {string}',
async (firstName: string, lastName: string, zipCode: string) => {
await new Purchase(getPage()).fillCheckoutInfo(firstName, lastName, zipCode);
}
);

Then('I select Continue', async () => {
await new Purchase(getPage()).continueCheckout();
});

Then('I select Finish', async () => {
await new Purchase(getPage()).finishCheckout();
});

Then('I should see the purchase confirmation {string}', async (expectedText: string) => {
await new Purchase(getPage()).validateConfirmation(expectedText);
});