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
5 changes: 5 additions & 0 deletions .idea/.gitignore

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

8 changes: 8 additions & 0 deletions .idea/Playwright-Cucumber-Exercise.iml

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

6 changes: 6 additions & 0 deletions .idea/inspectionProfiles/profiles_settings.xml

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

8 changes: 8 additions & 0 deletions .idea/modules.xml

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

6 changes: 6 additions & 0 deletions .idea/vcs.xml

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

6 changes: 4 additions & 2 deletions features/login.feature
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ 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'
# TODO: Add a step to validate the error message received
# TODO: Add a step to validate the error message received
Then the url should be "https://www.saucedemo.com/"
Then I should see the error "Epic sadface: Sorry, this user has been locked out."
8 changes: 6 additions & 2 deletions features/product.feature
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ Feature: Product Feature
Scenario Outline: Validate product sort by price <sort>
Then I will login as 'standard_user'
# TODO: Sort the items by <sort>
Then I will sort the items from "<sort>"
# TODO: Validate all 6 items are sorted correctly by price
Then I should see the products listed by price from "<sort>"
Examples:
# TODO: extend the datatable to paramterize this test
| sort |
# TODO: extend the datatable to parameterize this test
| sort |
| low to high |
| high to low |
10 changes: 8 additions & 2 deletions features/purchase.feature
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,17 @@ Feature: Purchase Feature
Given I open the "https://www.saucedemo.com/" page

Scenario: Validate successful purchase text
Then I will login as 'standard_user'
Then I will login with 'standard_user' as the user
Then I will add the backpack to the cart
# TODO: Select the cart (top-right)
Then I will go to the cart
# TODO: Select Checkout
Then I will click 'checkout'
# TODO: Fill in the First Name, Last Name, and Zip/Postal Code
Then I will fill in my First Name, Last Name, and Postal Code
# TODO: Select Continue
Then I will select continue
# TODO: Select Finish
# TODO: Validate the text 'Thank you for your order!'
Then I will click 'finish'
# TODO: Validate the text 'Thank you for your order!'
Then I should see the header 'Thank you for your order!'
9 changes: 8 additions & 1 deletion package-lock.json

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

27 changes: 26 additions & 1 deletion pages/login.page.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { Page } from "@playwright/test"
import exp from "node:constants";

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 errorBox:string = 'h3[data-test="error"]'

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

public async validateUrl(expectedUrl:string)
{
const pageUrl = this.page.url();
if (pageUrl !== expectedUrl)
{
throw new Error(`Expected url to be ${expectedUrl} but found ${pageUrl}`)
}
}

public async validateError(expectedError: string)
{
const errorText:string|null = await this.page.locator(this.errorBox).textContent()

// const errorText:string|null = await this.page.locator("").getAttribute("dir")

if (errorText !== expectedError)
{
throw new Error(`Expected error to be "${expectedError}" but found "${errorText}"`)
}
}
}


32 changes: 32 additions & 0 deletions pages/product.page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ import { Page } 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: string = 'select [class="product_sort_container"]'
private readonly hilo: string = 'option[value="hilo"]'
private readonly lohi: string = 'option[value="lohi"]'
private readonly inventoryList: string = 'div[class="inventory_list"]'


constructor(page: Page) {
this.page = page;
Expand All @@ -11,4 +16,31 @@ export class Product {
public async addBackPackToCart() {
await this.page.locator(this.addToCart).click()
}

public async sortHighToLow(){
await this.page.locator(this.sortDropDown).click()
await this.page.locator(this.hilo).click()
}

public async sortLowToHigh(){
await this.page.locator(this.sortDropDown).click()
await this.page.locator(this.lohi).click()
}

public async getListedPrices():Promise<number[]>
{
let itemList = await this.page.locator(this.inventoryList).allTextContents()

throw new Error(`recieved ${itemList}`)



}







}
67 changes: 67 additions & 0 deletions pages/purchase.page.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { Page } from "@playwright/test"
import exp from "node:constants";

export class Purchase {
// constants
private readonly page: Page
private readonly password: string = 'secret_sauce'
private readonly firstName: string = 'standard'
private readonly lastName: string = 'user'
private readonly postalCode: string = '12345'
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 firstNameField: string = 'input[id="first-name"]'
private readonly lastNameField: string = 'input[id="last-name"]'
private readonly postalCodeField: string = 'input[id="postal-code"]'
private readonly completeHeader: string = 'h2[class="complete-header"]'
private readonly continueButton: string = 'input[id="continue"]'


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

public async loginAsUser(userName: string) {
await this.page.locator(this.userNameField).fill(userName)
await this.page.locator(this.passwordField).fill(this.password)
await this.page.locator(this.loginButton).click()
}

public async goToCart(){
await this.page.locator('a[class="shopping_cart_link"]').click()
}

public async click(clickId: string){
await this.page.locator(`button[id="${clickId}"]`).click()
}

public async clickContinue(){
await this.page.locator(this.continueButton).click()
}

public async fillInInfo(){
await this.page.locator(this.firstNameField).fill(this.firstName)
await this.page.locator(this.lastNameField).fill(this.lastName)
await this.page.locator(this.postalCodeField).fill(this.postalCode)
}

public async validateComplete(expectedHeader: string){
const headerText:string|null = await this.page.locator(this.completeHeader).textContent()

if (headerText !== expectedHeader)
{
throw new Error(`Expected complete header to be "${expectedHeader}" but found "${headerText}"`)
}
}
}










17 changes: 16 additions & 1 deletion steps/login.steps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,19 @@ Then('I should see the title {string}', async (expectedTitle) => {

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

Then('the url should be {string}', async (url) =>
{
await new Login(getPage()).validateUrl(url);
});

Then('I should see the error {string}', async (errorMessage) =>
{
// const login = new Login(getPage())
// await login.loginAsUser("locked_out_user");
// await login.validateError(errorMessage);

await new Login(getPage()).validateError(errorMessage)
});

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

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

Then('Then I will sort the items from high to low', async () => {
await new Product(getPage()).sortHighToLow();
})

Then('Then I will sort the items from low to high', async () => {
await new Product(getPage()).sortLowToHigh();
})

Then('I should see the products listed by price from {string}', async (sort: string) =>
{
await new Product(getPage()).getListedPrices()
})

Then('Then I will sort the items from{string}', async (sort:string) =>
{
await new Product(getPage()).sortHighToLow();
}
)
Loading
Loading