Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
ab2bf6c
Initial commit: Playwright tests with TestDino integration
Aug 28, 2025
b96de44
Initial commit
Aug 29, 2025
199dffd
Initial commit
Aug 29, 2025
97516ee
Initial commit
Aug 29, 2025
776fe52
added more test cases
Aug 29, 2025
7382bcc
changes applied in the playwright.config file
testing123467 Sep 12, 2025
7e5bc7d
changes applied in the playwright.config file
testing123467 Sep 12, 2025
92cc7d0
updated the yml by adding multiple browser
testing123467 Sep 12, 2025
4dd014f
updated the yml by adding multiple browser
testing123467 Sep 12, 2025
3112535
updated the yml by adding multiple browser
testing123467 Sep 12, 2025
a1357e7
updated the yml by adding multiple browser
testing123467 Sep 12, 2025
4e30306
changes applied in the playwright.config file
testing123467 Sep 12, 2025
9d0753d
Updated playwright config
testing123467 Sep 22, 2025
ed4872a
Updated the workflow file with new updates
Feb 10, 2026
ffbe84c
Updated playwright.config file as well as workflow file
Feb 10, 2026
2253a48
Updated the playwright config file
Feb 10, 2026
2fa0b71
Updated test cases by adding tags/annotations feature
kriti2710 Mar 5, 2026
6b38fd2
Updated test cases by adding tags/annotations feature
kriti2710 Mar 5, 2026
4e574ac
Refactor Playwright test workflow configuration
kriti2710 Mar 7, 2026
f763542
Refactor Playwright configuration settings
kriti2710 Mar 7, 2026
d8c9add
Expand Playwright test grep filters to include API and mobile
kriti2710 Mar 7, 2026
cca4334
Increase shard count to 5 in test workflow
kriti2710 Mar 7, 2026
28f1040
Update Playwright config for retries and debugging
kriti2710 Mar 7, 2026
16086cb
Update Playwright test shard count to 5
kriti2710 Mar 7, 2026
33a1042
Enhance TestDino upload command with additional options
kriti2710 Mar 7, 2026
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
80 changes: 39 additions & 41 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -1,92 +1,85 @@
# .github/workflows/playwright-daily.yml
# Runs Playwright test shards every day at **11 : 42 AM IST** (06 : 12 UTC)
# plus anytime you trigger it manually from the Actions tab.

name: Run Playwright tests

on:
push:
pull_request:
schedule:
- cron: '30 3 * * 1-5'
- cron: '30 3 * * *' # 9:00 AM IST everyday # 11:00 AM IST
workflow_dispatch:

jobs:
run-tests:
name: Run Playwright shards
name: Run Playwright tests ${{ matrix.shardIndex }}/5
runs-on: ubuntu-latest

strategy:
fail-fast: false
matrix:
shardIndex: [1,2,3]
shardTotal: [2]
shardIndex: [1, 2, 3, 4, 5]
shardTotal: [5]

steps:
- uses: actions/checkout@v4

- name: Setup Node.js 18.x
- name: Setup Node.js 20.x
uses: actions/setup-node@v3
with:
node-version: '18'
node-version: "20"

- name: Create .env file
run: |
echo "USERNAME=${{ secrets.USERNAME }}" >> .env
echo "USERNAME1=${{ secrets.USERNAME1 }}" >> .env
echo "PASSWORD=${{ secrets.PASSWORD }}" >> .env
echo "NEW_PASSWORD=${{ secrets.NEW_PASSWORD }}" >> .env
echo "FIRST_NAME=${{ secrets.FIRST_NAME }}" >> .env
echo "STREET_NAME=${{ secrets.STREET_NAME }}" >> .env
echo "CITY=${{ secrets.CITY }}" >> .env
echo "STATE=${{ secrets.STATE }}" >> .env
echo "COUNTRY=${{ secrets.COUNTRY }}" >> .env
echo "ZIP_CODE=${{ secrets.ZIP_CODE }}" >> .env
echo "USERNAME=${{ secrets.USERNAME }}" >> .env
echo "PASSWORD=${{ secrets.PASSWORD }}" >> .env
echo "NEW_PASSWORD=${{ secrets.NEW_PASSWORD }}" >> .env
echo "FIRST_NAME=${{ secrets.FIRST_NAME }}" >> .env
echo "STREET_NAME=${{ secrets.STREET_NAME }}" >> .env
echo "CITY=${{ secrets.CITY }}" >> .env
echo "STATE=${{ secrets.STATE }}" >> .env
echo "COUNTRY=${{ secrets.COUNTRY }}" >> .env
echo "ZIP_CODE=${{ secrets.ZIP_CODE }}" >> .env

- name: Cache npm dependencies
uses: actions/cache@v3
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-

- name: Install deps + browsers
- name: Install dependencies
run: |
npm ci
npx playwright install --with-deps

- name: Run shard ${{ matrix.shardIndex }}
run: npx playwright test --project=chromium --reporter=blob --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }}
- name: Run Playwright Tests
run: |
npx playwright test \
--grep="@chromium|@firefox|@webkit|@api|@andriod|@ios" \
--shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }}

- name: Upload blob report
if: ${{ !cancelled() }}
uses: actions/upload-artifact@v4
with:
name: blob-report-${{ matrix.shardIndex }}
path: ./blob-report
retention-days: 1

merge-reports:

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium test

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}
name: Merge Reports
needs: run-tests
if: always() # run even if some shards fail
if: always()
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Setup Node.js 18.x
- name: Setup Node.js 20.x
uses: actions/setup-node@v3
with:
node-version: '18'

- name: Cache npm dependencies
uses: actions/cache@v3
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
node-version: "20"

- name: Install deps + browsers
- name: Install dependencies
run: |
npm ci
npx playwright install --with-deps
Expand All @@ -99,18 +92,23 @@
merge-multiple: true

- name: Merge HTML & JSON reports
run: npx playwright merge-reports --config=playwright.config.js ./all-blob-reports
run: |
npx playwright merge-reports \
--config=playwright.config.js \
./all-blob-reports

- name: Upload combined report
- name: Upload combined Playwright report
uses: actions/upload-artifact@v4
with:
name: Playwright Test Report
path: ./playwright-report
retention-days: 14

- name: Send TestDino report
- name: Upload report to TestDino
env:
TESTDINO_TOKEN: ${{ secrets.TESTDINO_TOKEN }}
run: |
npx --yes tdpw ./playwright-report \
--token="trx_production_75deca4b6fbb32963853ca189506496d60835761c32e54fd9f6787b00c86158f" \
npx tdpw upload ./playwright-report \
--upload-traces \
--upload-html \
--verbose
--token="$TESTDINO_TOKEN"
110 changes: 109 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,109 @@
# alphabin-demo-test-playwright
# Ecommerce demo store - Playwright (javascript) tests

Automated end-to-end tests for Ecommerce demo store using [Playwright](https://playwright.dev/).

---

## Project Structure

- `pages/` — Page Object Models
- `tests/` — Test specifications
- `playwright.config.js` — Playwright configuration
- `playwright-report/` — HTML test reports
- `.github/workflows/test.yml` — CI/CD pipeline

---

## Prerequisites

- [Node.js](https://nodejs.org/) v16+
- [npm](https://www.npmjs.com/)

---

## Installation

```sh
npm install
```

---

## Local Test Execution

Run all tests:
```sh
npx playwright test
```

View the HTML report:
```sh
npx playwright show-report
```

---

## Testdino Integration

[Testdino](https://testdino.com/) enables cloud-based Playwright reporting.

> **Important:**
> Make sure your `playwright.config.js` includes both the HTML and JSON reporters.
> The HTML report and JSON report must be available for Testdino to process your test results.

Example configuration:
```js
reporter: [
['html', { outputFolder: 'playwright-report', open: 'never' }],
['json', { outputFile: './playwright-report/report.json' }],
]
```

### Local Execution

After your tests complete and the report is generated in `playwright-report`, upload it to Testdino:

```sh
npx --yes tdpw ./playwright-report --token="YOUR_TESTDINO_API_KEY" --upload-html
```

Replace the token above with your own Testdino API key.

See all available commands:
```sh
npx tdpw --help
```

---

## CI/CD Pipeline Integration

### GitHub Actions

Add the following step to your workflow after tests and report generation:

```yaml
- name: Send Testdino report
run: |
npx --yes tdpw ./playwright-report --token="YOUR_TESTDINO_API_KEY" --upload-html
```

Ensure your API key is correctly placed in the command.

---

## Continuous Integration

Automated test runs and report merging are configured in `.github/workflows/test.yml`.

---

## Contributing

Pull requests and issues are welcome!

---

## License

MIT
3 changes: 3 additions & 0 deletions pages/AllPages.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import CheckoutPage from "./CheckoutPage";
import OrderPage from "./OrderPage"; // Import OrderPage
import UserPage from "./UserPage"; // Import UserPage
import OrderDetailsPage from "./OrderDetailsPage";
import ContactUsPage from "./ContactUsPage";

class AllPages {
constructor(page) {
Expand All @@ -24,6 +25,8 @@ class AllPages {
this.orderPage = new OrderPage(page); // Instantiate OrderPage
this.userPage = new UserPage(page); // Instantiate UserPage
this.orderDetailsPage = new OrderDetailsPage(page);
this.contactUsPage = new ContactUsPage(page);

}
}

Expand Down
25 changes: 25 additions & 0 deletions pages/CartPage.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { start } from 'repl';
import BasePage from './BasePage.js';
import { expect } from '@playwright/test';

Expand Down Expand Up @@ -29,6 +30,9 @@ class CartPage extends BasePage{
checkoutButton: '[data-testid="checkout-button"]',
viewCartButton: '[data-testid="view-cart-button"]',
shoppingCartIcon: `[data-testid="header-cart-icon"]`,
deleteItemButton: '[aria-label="Remove item"]',
cartEmpty: `[data-testid="empty-cart"]`,
startShoppingButton: `[data-testid="continue-shopping-btn"]`
}

async assertYourCartTitle() {
Expand Down Expand Up @@ -124,6 +128,27 @@ class CartPage extends BasePage{
await this.page.waitForTimeout(2000);
await this.page.locator(this.locators.checkoutButton).click({ force: true });
}

async verifyIncreasedQuantity(expectedQuantity) {
await expect(this.page.locator(this.locators.cartItemQuantity)).toHaveText(expectedQuantity);
}

async clickOnDeleteProductIcon() {
await this.page.locator(this.locators.deleteItemButton).click();
}

async verifyCartItemDeleted() {
await expect(this.page.locator(this.locators.cartItemName)).toHaveCount(0);
}

async verifyEmptyCartMessage() {
await expect(this.page.locator(this.locators.cartEmpty)).toBeVisible();
}

async clickOnStartShoppingButton() {
await this.page.locator(this.locators.startShoppingButton).click();
}

}

export default CartPage;
40 changes: 40 additions & 0 deletions pages/ContactUsPage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import BasePage from './BasePage.js';
import { expect } from '@playwright/test';

class ContactUsPage extends BasePage{

/**
* @param {import('@playwright/test').Page} page
*/
constructor(page) {
super(page);
this.page = page;
}

locators = {
contactUsBtn: `[data-testid="header-menu-contact-us"]`,
contactUsTitle: `[data-testid="contact-us-heading"]`,
firstNameInput: `[data-testid="contact-us-first-name-input"]`,
lastNameInput: `[data-testid="contact-us-last-name-input"]`,
subjectInput: `[data-testid="contact-us-subject-input"]`,
messageInput: `[data-testid="contact-us-message-input"]`,
sendMessageBtn: `//button[@data-testid="contact-us-submit-button"]`,
successMessage: `[data-testid="contact-us-success-message"]`
}

async assertContactUsTitle() {
await expect(this.page.locator(this.locators.contactUsTitle)).toHaveText('Contact Us');
}

async fillContactUsForm() {
await this.page.fill(this.locators.firstNameInput, 'John');
await this.page.fill(this.locators.lastNameInput, 'Doe');
await this.page.fill(this.locators.subjectInput, 'Test Subject');
await this.page.fill(this.locators.messageInput, 'This is a test message.');
await this.page.click(this.locators.sendMessageBtn);
}
async verifySuccessContactUsFormSubmission() {
await expect(this.page.locator(this.locators.successMessage)).toBeVisible();
}
}
export default ContactUsPage;
22 changes: 21 additions & 1 deletion pages/HomePage.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ class HomePage extends BasePage{
AddCartNotification: `div[role="status"][aria-live="polite"]:has-text("Added to the cart")`,
priceRangeSlider2 : `[data-testid="all-products-price-range-input-1"]`,
priceRangeSlider1 : `[data-testid="all-products-price-range-input-0"]`,
filterButton : `[data-testid="all-products-filter-toggle"]`
filterButton : `[data-testid="all-products-filter-toggle"]`,
aboutUsTitle: `[data-testid="about-us-title"]`,
}
}

Expand Down Expand Up @@ -88,6 +89,25 @@ class HomePage extends BasePage{
return this.page.locator(this.locators.navbar.showNowButton);
}

async clickOnContactUsLink() {
await this.getContactUsNav().click();
}

async clickBackToHomeButton() {
await this.getHomeNav().click();
}

async assertHomePage() {
await expect(this.page.locator(this.locators.navbar.homeNav)).toBeVisible({ timeout: 10000 });
}

async clickAboutUsNav() {
await this.getAboutUsNav().click();
}

async assertAboutUsTitle() {
await expect(this.page.locator(this.locators.navbar.aboutUsTitle)).toBeVisible({ timeout: 10000 });
}
}

export default HomePage;
Loading
Loading