Skip to content

Commit 7ffac10

Browse files
committed
Adding new test case 'Shopping Experince'
1 parent dc3ee82 commit 7ffac10

File tree

9 files changed

+255
-27
lines changed

9 files changed

+255
-27
lines changed

‎.vscode/launch.json

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,31 @@
7777
"internalConsoleOptions": "openOnSessionStart"
7878
},
7979
// Test Case: 4 --------------->>>>
80+
{
81+
"type": "node",
82+
"request": "launch",
83+
"name": "[restrictedAccessTest]: Validate End-to-End Shopping Process for a Specific Product",
84+
"runtimeArgs": [
85+
"-r",
86+
"ts-node/register"
87+
],
88+
"args": [
89+
"${workspaceFolder}/node_modules/mocha/bin/_mocha",
90+
"--timeout", "999999",
91+
"--colors",
92+
"${workspaceFolder}/test/shoppingExp.ts"
93+
],
94+
"cwd": "${workspaceRoot}",
95+
"env": {
96+
"NODE_ENV": "test",
97+
"PERFHUB_ENABLED": "false"
98+
},
99+
"sourceMaps": true,
100+
"skipFiles": ["<node_internals>/**"],
101+
"console": "internalConsole",
102+
"internalConsoleOptions": "openOnSessionStart",
103+
},
104+
// Test Case: Regression --------------->>>>
80105
{
81106
"type": "node",
82107
"request": "launch",

‎src/app.ts

Lines changed: 52 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ export class App {
3333
return driver;
3434
}
3535

36-
// ---URL---
36+
// ---URL--- ------------->>>
3737
async verifyUrl(expectedUrl: string) {
3838
try {
3939
// Retrieve the page url and assert
@@ -46,8 +46,7 @@ export class App {
4646
}
4747

4848

49-
// ---LOGIN_PAGE---
50-
49+
// ---LOGIN_PAGE--- ------------->>>
5150
async verifyTitle() {
5251
const expectedTitle = 'Swag Labs';
5352
try {
@@ -91,8 +90,56 @@ export class App {
9190
}
9291
}
9392

94-
// ---INTERACTION---
95-
93+
async verifyText(locator: By, expectedText: string) {
94+
try {
95+
// Wait for the element to be located
96+
const element = await this.driver.wait(until.elementLocated(locator), 5000);
97+
98+
// Retrieve the element's text and assert
99+
const actualText = await element.getText();
100+
assert.equal(actualText, expectedText, `Expected text '${expectedText}', but found '${actualText}'`);
101+
} catch (error) {
102+
console.error('Error in verifyText:', error);
103+
throw error;
104+
}
105+
}
106+
107+
// ---CHECKOUT_PAGE_FUNCTION--- ------------->>>
108+
async verifyCartCount(expectedCount: string) {
109+
try {
110+
// Wait for the element to be located
111+
const element = await this.driver.wait(until.elementLocated(By.css(compMain.cartBadge)), 5000);
112+
113+
// Retrieve the element's text and assert
114+
const actualCount = await element.getText();
115+
assert.equal(actualCount, expectedCount, `Expected text '${expectedCount}', but found '${actualCount}'`);
116+
} catch (error) {
117+
console.error('Error in verifyCartCount:', error);
118+
throw error;
119+
}
120+
}
121+
122+
async getItemQty() {
123+
try {
124+
const elements = await this.driver.findElements(By.css(compMain.inBasketItem));
125+
return elements.length;
126+
} catch (error) {
127+
console.error('Error in getItemQty:', error);
128+
throw error;
129+
}
130+
}
131+
132+
async verifyItemQty(expectedQty: number) {
133+
try {
134+
const actualQty = await this.getItemQty();
135+
assert.equal(actualQty, expectedQty, `Expected quantity '${expectedQty}', but found '${actualQty}'`);
136+
} catch (error) {
137+
console.error('Error in verifyItemQty:', error);
138+
throw error;
139+
}
140+
}
141+
142+
// ---INTERACTION--- ------------->>>
96143
async insertText(locator: By, text: string) {
97144
try {
98145
// Wait for the element to be located and interactable

‎src/components/data/data.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
export enum DataURL {
22
saucedemo = 'https://www.saucedemo.com/',
3-
saucedemoInventory = 'https://www.saucedemo.com/inventory.html'
3+
saucedemoInventory = 'https://www.saucedemo.com/inventory.html',
4+
saucedemoCheckoutComplete = 'https://www.saucedemo.com/checkout-complete.html'
45
}

‎src/components/main.ts

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,33 @@
11
export class Main {
2-
get title() {return '#root > div > div.login_logo';}
3-
4-
get userNameInput() {return 'user-name';}
5-
6-
get userPassInput() {return 'password';}
7-
8-
get loginButtion() {return 'login-button';}
92

3+
// Login Page Selectors
4+
get title() {return '#root > div > div.login_logo';}
5+
get userNameInput() {return '[id="user-name"]';}
6+
get userPassInput() {return '[id="password"]';}
7+
get loginButton() {return '[id="login-button"]';}
108
get loginErrorMsg() {return '[data-test="error"]';}
9+
get errorMsgCloseBtn() {return '[data-test="error"] > button';}
1110

11+
// Error Message Selectors
1212
get restrictedErrorMsg() {return '[class="error-message-container error"]';}
1313

14-
get errorMsgCloseBtn() {return '[data-test="error"] > button';}
14+
// Product Page Selectors
15+
get yourCart() {return 'span[class="title"]';}
16+
get addToCartBtn() {return '[class="btn btn_primary btn_small btn_inventory"]';}
17+
get removeCartBtn() {return '[class="btn btn_secondary btn_small btn_inventory"]';}
18+
get sauceLabsBackpack() {return '[id="item_4_title_link"]';} // Specific product
19+
20+
// Cart Selectors
21+
get cartBadge() {return 'span[class="shopping_cart_badge"]';}
22+
get checkoutBtn() {return 'button[id="checkout"]';}
23+
get cartBtn() {return '[id="shopping_cart_container"]';} // Interaction
24+
get inBasketItem() {return '[class="cart_item"]';}
25+
26+
// Checkout Page Selectors
27+
get firstName() {return '[id="first-name"]';}
28+
get lastName() {return '[id="last-name"]';}
29+
get postalCode() {return '[id="postal-code"]';}
30+
get continueBtn() {return '[id="continue"]';}
31+
get finishBtn() {return '[id="finish"]';}
32+
get completeHeader() {return 'h2[class="complete-header"]';}
1533
}

‎test/invalidLoginTest.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ describe('Test Case: Validate Unsuccessful Login', async function () {
1313
let driver: WebDriver;
1414

1515
before(async function () {
16-
// driver = await App.buildDriver();
16+
driver = await App.buildDriver();
1717
driver = await new Builder().forBrowser('chrome').build();
1818
objApp = new App(driver); // Pass the driver instance here
1919
await driver.manage().window().maximize(); // Maximize the browser window
@@ -30,15 +30,15 @@ describe('Test Case: Validate Unsuccessful Login', async function () {
3030
});
3131

3232
it('Step 2: Enter invalid username', async function () {
33-
await objApp.insertText(By.id(compMain.userNameInput), 'invalid_user');
33+
await objApp.insertText(By.css(compMain.userNameInput), 'invalid_user');
3434
});
3535

3636
it('Step 3: Enter invalid password', async function () {
37-
await objApp.insertText(By.id(compMain.userPassInput), 'wrong_password');
37+
await objApp.insertText(By.css(compMain.userPassInput), 'wrong_password');
3838
});
3939

4040
it('Step 4: Click Login', async function () {
41-
await objApp.click(By.id(compMain.loginButtion));
41+
await objApp.click(By.css(compMain.loginButton));
4242

4343
await objApp.verifyErrorMsg(`Epic sadface: Username and password do not match any user in this service`);
4444
});

‎test/restrictedAccessTest.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ import { DataURL } from '../src/components/data/data';
99
let compMain = new Main();
1010
let objApp: App;
1111

12-
describe('Test Case: Validate Successful Login', async function () {
12+
describe('Test Case: Retrict Direct Access', async function () {
1313
let driver: WebDriver;
1414

1515
before(async function () {
16-
// driver = await App.buildDriver();
17-
driver = await new Builder().forBrowser('firefox').build();
16+
driver = await App.buildDriver();
17+
driver = await new Builder().forBrowser('chrome').build();
1818
objApp = new App(driver); // Pass the driver instance here
1919
await driver.manage().window().maximize(); // Maximize the browser window
2020
});

‎test/shoppingExp.ts

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
import { expect, assert} from 'chai';
2+
import { WebDriver, Builder, By } from 'selenium-webdriver';
3+
import * as chrome from 'selenium-webdriver/chrome';
4+
import 'chromedriver';
5+
import { Main } from '../src/components/main';
6+
import { App } from '../src/app';
7+
import { DataURL } from '../src/components/data/data';
8+
9+
let compMain = new Main();
10+
let objApp: App;
11+
12+
describe('Test Case: Validate End-to-End Shopping Process for a Specific Product', async function () {
13+
let driver: WebDriver;
14+
15+
before(async function () {
16+
driver = await App.buildDriver();
17+
driver = await new Builder().forBrowser('chrome').build();
18+
objApp = new App(driver); // Pass the driver instance here
19+
await driver.manage().window().maximize(); // Maximize the browser window
20+
});
21+
22+
after(async function () {
23+
await driver.quit(); // Close the driver after each test case
24+
});
25+
26+
it('Step 1: Open Browser', async function () {
27+
await driver.get('https://www.saucedemo.com'); // Navigate to the website
28+
29+
await objApp.verifyUrl(DataURL.saucedemo);
30+
});
31+
32+
it('Step 2: Enter valid username & password', async function () {
33+
await objApp.insertText(By.css(compMain.userNameInput), 'standard_user');
34+
35+
await objApp.insertText(By.css(compMain.userPassInput), 'secret_sauce');
36+
});
37+
38+
it('Step 3: Click Login', async function () {
39+
await objApp.click(By.css(compMain.loginButton));
40+
41+
await objApp.verifyUrl(DataURL.saucedemoInventory);
42+
});
43+
44+
it('Step 4: Click on the "Sauce Labs Backpack"', async function () {
45+
// Find the text 'Sauce Labs Backpack' and click on it
46+
await objApp.click(By.css(compMain.sauceLabsBackpack));
47+
});
48+
49+
it('Step 5: Click on the "Add to Cart" button', async function () {
50+
// Find the text 'Add to cart' and click on it
51+
await objApp.click(By.css(compMain.addToCartBtn));
52+
53+
// Verify the text 'Remove' is displayed
54+
await objApp.verifyText(By.css(compMain.removeCartBtn), 'Remove');
55+
});
56+
57+
it('Step 6: Click on the "Cart" button', async function () {
58+
// Find the text 'Cart' and click on it
59+
await objApp.click(By.css(compMain.cartBtn));
60+
61+
// Verify the text 'Your Cart' is displayed
62+
await objApp.verifyText(By.css(compMain.yourCart), 'Your Cart');
63+
64+
// Verify the cart badge is indicated as '1'
65+
await objApp.verifyText(By.css(compMain.cartBadge), '1');
66+
67+
// Verify the total item in the cart
68+
await objApp.verifyItemQty(1)
69+
});
70+
71+
it('Step 7: Click on the "Checkout" button', async function () {
72+
// Find the text 'Checkout' and click on it
73+
await objApp.click(By.css(compMain.checkoutBtn));
74+
});
75+
76+
it('Step 8: Enter Checkout Details', async function () {
77+
// Enter First Name
78+
await objApp.insertText(By.css(compMain.firstName), 'John');
79+
80+
// Enter Last Name
81+
await objApp.insertText(By.css(compMain.lastName), 'Doe');
82+
83+
// Enter Zip Code
84+
await objApp.insertText(By.css(compMain.postalCode), '12345');
85+
});
86+
87+
it('Step 9: Click on the "Continue" button', async function () {
88+
// Find the text 'Continue' and click on it
89+
await objApp.click(By.css(compMain.continueBtn));
90+
});
91+
92+
it('Step 10: Click on the "Finish" button', async function () {
93+
// Find the text 'Finish' and click on it
94+
await objApp.click(By.css(compMain.finishBtn));
95+
\
96+
// Verify the URL
97+
await objApp.verifyUrl(DataURL.saucedemoCheckoutComplete);
98+
99+
// Verify the text 'Thank you for your order!' is displayed
100+
await objApp.verifyText(By.css(compMain.completeHeader), 'Thank you for your order!');
101+
});
102+
103+
104+
105+
106+
107+
108+
});
109+
110+

‎test/validLoginTest.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,15 @@ import { App } from '../src/app';
77
import { DataURL } from '../src/components/data/data';
88

99
let compMain = new Main();
10-
let ObjApp: App;
10+
let objApp: App;
1111

1212
describe('Test Case: Validate Successful Login', async function () {
1313
let driver: WebDriver;
1414

1515
before(async function () {
1616
driver = await App.buildDriver();
1717
driver = await new Builder().forBrowser('chrome').build();
18-
ObjApp = new App(driver); // Pass the driver instance here
18+
objApp = new App(driver); // Pass the driver instance here
1919
await driver.manage().window().maximize(); // Maximize the browser window
2020
});
2121

@@ -26,19 +26,19 @@ describe('Test Case: Validate Successful Login', async function () {
2626
it('Step 1: Open Browser', async function () {
2727
await driver.get('https://www.saucedemo.com'); // Navigate to the website
2828

29-
await ObjApp.verifyTitle();
29+
await objApp.verifyTitle();
3030
});
3131

3232
it('Step 2: Input in the application with valid username', async function () {
33-
await ObjApp.insertText(By.id(compMain.userNameInput), 'standard_user');
33+
await objApp.insertText(By.css(compMain.userNameInput), 'standard_user');
3434
});
3535

3636
it('Step 3: Input in the application with valid password', async function () {
37-
await ObjApp.insertText(By.id(compMain.userPassInput), 'secret_sauce ');
37+
await objApp.insertText(By.css(compMain.userPassInput), 'secret_sauce ');
3838
});
3939

4040
it('Step 4: Click on the login button', async function () {
41-
await ObjApp.click(By.id(compMain.loginButtion));
41+
await objApp.click(By.css(compMain.loginButton));
4242
});
4343
});
4444

‎test_case/shoppingExp.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Test Case: Validate End-to-End Shopping Process for a Specific Product
2+
3+
**Objective:** To verify that users can successfully log in, select a specific product ('Sauce Labs Backpack'), add it to the cart, and complete the checkout process.
4+
5+
**Preconditions:**
6+
- The user must have a valid username and password (`standard_user` / `secret_sauce`).
7+
- The website, "https://www.saucedemo.com/", should be operational.
8+
9+
## Test Procedure and Expected Results
10+
11+
| Step | Action | Expected Result |
12+
|------|--------|-----------------|
13+
| 1 | Launch Browser: Open the browser and navigate to "https://www.saucedemo.com/". | The login page of Saucedemo should be displayed. |
14+
| 2 | Enter Credentials: Input `standard_user` in the username field and `secret_sauce` in the password field. | Correct credentials should be entered in their respective fields. |
15+
| 3 | Login: Click the login button. | The products page should be loaded, displaying various products. with the expected url `https://www.saucedemo.com/inventory.html` |
16+
| 4 | Select Product: Locate and click on the 'Sauce Labs Backpack'. | The detail page for 'Sauce Labs Backpack' should be displayed, showing price and description. |
17+
| 5 | Add to Cart: Click on the "Add to Cart" button for 'Sauce Labs Backpack'. | The 'Sauce Labs Backpack' should be added to the cart. The cart icon should show a count of 1. |
18+
| 6 | View Cart: Click on the shopping cart icon. | The cart page should display 'Sauce Labs Backpack' as a listed item. |
19+
| 7 | Checkout: Click on the "Checkout" button. | The checkout information page should be displayed. |
20+
| 8 | Enter Checkout Details: Input first name, last name, and zip code in the respective fields. | Provided checkout information should be entered correctly. |
21+
| 9 | Continue: Click on the "Continue" button. | The overview page listing 'Sauce Labs Backpack' along with its price and total should be displayed. |
22+
| 10 | Finalize Purchase: Click on the "Finish" button. | A confirmation page with a message like "Thank you for your order" should be displayed, indicating successful purchase. |
23+
24+
## Post-Conditions:
25+
26+
- The user should log out by clicking the logout link in the menu.
27+
- The browser should be closed, resetting the application for future tests.

0 commit comments

Comments
 (0)