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
60 changes: 60 additions & 0 deletions cypress/support/saucedemo-purchase.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/// <reference types="cypress" />

describe('SauceDemo Purchase Flow', () => {
beforeEach(() => {
// Visit the SauceDemo site before each test
cy.visit('https://www.saucedemo.com/');
});

it('should complete a purchase successfully', () => {
// ---- Step 1: Log in ----
// Using standard demo credentials from the official site
cy.get('[data-test="username"]').type('standard_user');
cy.get('[data-test="password"]').type('secret_sauce');
cy.get('[data-test="login-button"]').click();

// Assertion: Check if redirected to inventory page
cy.url().should('include', '/inventory.html');
cy.get('.title').should('have.text', 'Products');

// ---- Step 2: Sort items by price (low to high) ----
cy.get('[data-test="product-sort-container"]').select('Price (low to high)');
// Verify sorting dropdown works
cy.get('[data-test="product-sort-container"]').should('have.value', 'lohi');

// ---- Step 3: Add at least one item to the cart ----
cy.get('.inventory_item').first().within(() => {
cy.get('button').click(); // Click "Add to cart"
});

// Assert cart badge shows 1 item
cy.get('.shopping_cart_badge').should('have.text', '1');

// ---- Step 4: Go to the cart and proceed to checkout ----
cy.get('.shopping_cart_link').click();
cy.url().should('include', '/cart.html');
cy.contains('Your Cart').should('be.visible');

cy.get('[data-test="checkout"]').click();

// ---- Step 5: Fill in checkout info ----
cy.get('[data-test="firstName"]').type('John');
cy.get('[data-test="lastName"]').type('Doe');
cy.get('[data-test="postalCode"]').type('12345');
cy.get('[data-test="continue"]').click();

// ---- Step 6: Review & Complete the purchase ----
cy.url().should('include', '/checkout-step-two.html');
cy.contains('Payment Information').should('be.visible');

cy.get('[data-test="finish"]').click();

// ---- Step 7: Assert that the order was successful ----
cy.url().should('include', '/checkout-complete.html');
cy.get('.complete-header').should('have.text', 'Thank you for your order!');
cy.get('.complete-text').should('contain', 'Your order has been dispatched');

// Optional: Verify back home button
cy.get('[data-test="back-to-products"]').should('be.visible');
});
});
23 changes: 23 additions & 0 deletions newman/project-env.postman_environment.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"id": "1d4e505d-594b-4ac1-bf52-fabcae102b42",
"name": "jsonplaceholder-env",
"values": [
{
"key": "baseUrl",
"value": "",
"type": "default",
"description": "Base API endpoint",
"enabled": true
},
{
"key": "postId",
"value": "",
"type": "default",
"description": "Used to store dynamically created post ID",
"enabled": true
}
],
"_postman_variable_scope": "environment",
"_postman_exported_at": "2025-10-18T17:03:12.219Z",
"_postman_exported_using": "Postman/11.67.5-251017-0111"
}
205 changes: 205 additions & 0 deletions newman/project.postman_collection.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
{
"info": {
"_postman_id": "9af4fb24-e51f-4df8-91a8-dc23c0cad94b",
"name": "jsonplaceholder.postman_collection.json",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
"_exporter_id": "7368615"
},
"item": [
{
"name": "New Request",
"event": [
{
"listen": "prerequest",
"script": {
"exec": [
""
],
"type": "text/javascript",
"packages": {},
"requests": {}
}
},
{
"listen": "test",
"script": {
"exec": [
"pm.test(\"Status code is 200\", function () {",
" pm.response.to.have.status(200);",
"});",
"",
"pm.test(\"Response should be an array with at least one post\", function () {",
" const jsonData = pm.response.json();",
" pm.expect(jsonData.length).to.be.above(0);",
"});"
],
"type": "text/javascript",
"packages": {},
"requests": {}
}
}
],
"request": {
"method": "GET",
"header": [],
"url": {
"raw": "{{baseUrl}}/posts",
"host": [
"{{baseUrl}}"
],
"path": [
"posts"
]
}
},
"response": []
},
{
"name": "New Request",
"event": [
{
"listen": "test",
"script": {
"exec": [
"const jsonData = pm.response.json();",
"",
"pm.test(\"Status code is 201 (Created)\", function () {",
" pm.response.to.have.status(201);",
"});",
"",
"pm.test(\"Response contains title and id\", function () {",
" pm.expect(jsonData).to.have.property('id');",
" pm.expect(jsonData).to.have.property('title', 'My automated post');",
"});",
"",
"// Save the id for use in later requests",
"pm.environment.set(\"postId\", jsonData.id);"
],
"type": "text/javascript",
"packages": {},
"requests": {}
}
}
],
"request": {
"method": "POST",
"header": [],
"body": {
"mode": "raw",
"raw": "{\n \"title\": \"My automated post\",\n \"body\": \"This post was created via Postman + Newman test\",\n \"userId\": 1\n}\n",
"options": {
"raw": {
"language": "json"
}
}
},
"url": {
"raw": "{{baseUrl}}/posts",
"host": [
"{{baseUrl}}"
],
"path": [
"posts"
]
}
},
"response": []
},
{
"name": "New Request",
"event": [
{
"listen": "test",
"script": {
"exec": [
"pm.test(\"Status code is 200\", () => {",
" pm.response.to.have.status(200);",
"});",
"",
"pm.test(\"Title updated correctly\", () => {",
" let jsonData = pm.response.json();",
" pm.expect(jsonData.title).to.eql(\"Updated Title\");",
"});",
""
],
"type": "text/javascript",
"packages": {},
"requests": {}
}
},
{
"listen": "prerequest",
"script": {
"exec": [
""
],
"type": "text/javascript",
"packages": {},
"requests": {}
}
}
],
"request": {
"method": "PUT",
"header": [],
"body": {
"mode": "raw",
"raw": "{\n \"id\": 1,\n \"title\": \"Updated Title\",\n \"body\": \"Updated body content\",\n \"userId\": 1\n}",
"options": {
"raw": {
"language": "json"
}
}
},
"url": {
"raw": "{{baseUrl}}/posts/1",
"host": [
"{{baseUrl}}"
],
"path": [
"posts",
"1"
]
}
},
"response": []
},
{
"name": "New Request",
"event": [
{
"listen": "test",
"script": {
"exec": [
"pm.test(\"Status code is 200 (OK)\", function () {",
" pm.response.to.have.status(200);",
"});",
"",
"pm.test(\"Response body is empty object\", function () {",
" pm.expect(pm.response.text()).to.eql('{}');",
"});"
],
"type": "text/javascript",
"packages": {},
"requests": {}
}
}
],
"request": {
"method": "DELETE",
"header": [],
"url": {
"raw": "{{baseUrl}}/posts/{{postId}}",
"host": [
"{{baseUrl}}"
],
"path": [
"posts",
"{{postId}}"
]
}
},
"response": []
}
]
}