fixing tha playwright
Some checks failed
Beta CI/CD Pipeline / build-and-test (push) Failing after 41s
Beta CI/CD Pipeline / deploy-beta (push) Has been skipped

This commit is contained in:
vickytechkey 2026-08-14 15:25:47 +05:30
parent 3cd4ed1641
commit d4f495fef7
18 changed files with 1219 additions and 1 deletions

64
package-lock.json generated
View file

@ -12,6 +12,7 @@
"react-dom": "^19.2.8"
},
"devDependencies": {
"@playwright/test": "^1.49.0",
"@testing-library/dom": "^10.4.1",
"@testing-library/jest-dom": "^7.0.0",
"@testing-library/react": "^16.3.2",
@ -697,6 +698,22 @@
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@playwright/test": {
"version": "1.62.1",
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.62.1.tgz",
"integrity": "sha512-DTcUc8qii+cpHvtOwggMtBRMjKZHXYWdw8syRYu2vtzuq4Wxphqq4NfCs5Zt44L6mA8rfDfj+PHnxFc/FeK6mQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"playwright": "1.62.1"
},
"bin": {
"playwright": "cli.js"
},
"engines": {
"node": ">=20"
}
},
"node_modules/@polka/url": {
"version": "1.0.0-next.29",
"resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz",
@ -3453,6 +3470,53 @@
"node": ">=0.10.0"
}
},
"node_modules/playwright": {
"version": "1.62.1",
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.62.1.tgz",
"integrity": "sha512-0M+L3LAD8/nm554LOla9Ayx0j0tmFZ0FBcoQ7F1VuVHpM/XpiC8RcDzBQB8W5+hA8L22THxELzeF+2WcUzvcLg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"playwright-core": "1.62.1"
},
"bin": {
"playwright": "cli.js"
},
"engines": {
"node": ">=20"
},
"optionalDependencies": {
"fsevents": "2.3.2"
}
},
"node_modules/playwright-core": {
"version": "1.62.1",
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.62.1.tgz",
"integrity": "sha512-wPYSwEBJY9GHraISXqyqtx0na0LpO3XEX7jNDhntbex7tzUS7kLnZsOlFruFJB4Hi/rhDMjXGqHewDZ68nYZVw==",
"dev": true,
"license": "Apache-2.0",
"bin": {
"playwright-core": "cli.js"
},
"engines": {
"node": ">=20"
}
},
"node_modules/playwright/node_modules/fsevents": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
}
},
"node_modules/postcss": {
"version": "8.5.26",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.26.tgz",

View file

@ -10,13 +10,15 @@
"test": "vitest run",
"preview": "vite preview",
"cypress:run": "cypress run --headed",
"cypress:open": "cypress open"
"cypress:open": "cypress open",
"test:playwright": "playwright test --project=chromium"
},
"dependencies": {
"react": "^19.2.8",
"react-dom": "^19.2.8"
},
"devDependencies": {
"@playwright/test": "^1.49.0",
"@testing-library/dom": "^10.4.1",
"@testing-library/jest-dom": "^7.0.0",
"@testing-library/react": "^16.3.2",

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

View file

@ -0,0 +1,209 @@
# Instructions
- Following Playwright test failed.
- Explain why, be concise, respect Playwright best practices.
- Provide a snippet of code with the fix, if possible.
# Test info
- Name: onboarding.spec.ts >> Supplier Portal Onboarding & Feature E2E Flow >> completes the registration, contact verification, document upload, location pinning, welcome tour, order acceptance, and barcode generation
- Location: playwright/e2e/onboarding.spec.ts:4:3
# Error details
```
Error: expect(locator).toBeVisible() failed
Locator: getByText('Step 1 of 3: Contact Verification')
Expected: visible
Timeout: 5000ms
Error: element(s) not found
Call log:
- Expect "toBeVisible" with timeout 5000ms
- waiting for getByText('Step 1 of 3: Contact Verification')
```
```yaml
- banner:
- text: A Global Artisans Hub
- navigation:
- button "Platform"
- button "Pricing"
- button "Success Stories"
- button "Support"
- button "Login"
- button "Get Started"
- main:
- button "Login"
- button "Register"
- heading "Create Your Supplier Account" [level=2]
- text: Business Email *
- textbox "Business Email *":
- /placeholder: Enter email address
- text: test_seller_1786700927358@example.com
- text: Mobile Number *
- textbox "Mobile Number *":
- /placeholder: Enter 10-digit number
- text: "9118192284"
- text: Create Password *
- textbox "Create Password *":
- /placeholder: Minimum 8 characters
- text: Super_secure_pass_123!
- button "🙈"
- text: Confirm Password *
- textbox "Confirm Password *":
- /placeholder: Re-enter password
- text: Super_secure_pass_123!
- button "🙈"
- checkbox "I accept the Terms of Service and Privacy Policy *" [checked]
- text: I accept the
- link "Terms of Service":
- /url: "#terms"
- text: and
- link "Privacy Policy":
- /url: "#privacy"
- text: "*"
- button "Register Business"
- contentinfo:
- text: Global Artisans Hub
- link "About Us":
- /url: "#about"
- link "Careers":
- /url: "#careers"
- link "Press":
- /url: "#press"
- link "Terms":
- /url: "#terms"
- link "Privacy":
- /url: "#privacy"
- text: © 2026 Global Artisans Hub. All rights reserved.
```
# Test source
```ts
1 | import { test, expect } from '@playwright/test';
2 |
3 | test.describe('Supplier Portal Onboarding & Feature E2E Flow', () => {
4 | test('completes the registration, contact verification, document upload, location pinning, welcome tour, order acceptance, and barcode generation', async ({ page }) => {
5 | // 1. Visit Landing Page
6 | await page.goto('/');
7 | await expect(page.getByText('Sell Globally.')).toBeVisible();
8 |
9 | // 2. Registration Page
10 | await page.locator('button, a').filter({ hasText: 'Get Started Today' }).first().click();
11 | const randUser = `test_seller_${Date.now()}@example.com`;
12 | const randPhone = `9${Math.floor(100000000 + Math.random() * 900000000)}`;
13 | await page.locator('input#reg-email').fill(randUser);
14 | await page.locator('input#reg-phone').fill(randPhone);
15 | await page.locator('input#reg-pass').fill('Super_secure_pass_123!');
16 | await page.locator('input#reg-confirm-pass').fill('Super_secure_pass_123!');
17 | await page.locator('input#reg-policy').check();
18 | await page.locator('button').filter({ hasText: 'Register Business' }).click();
19 |
20 | // 3. Step 1: Contact Verification
> 21 | await expect(page.getByText('Step 1 of 3: Contact Verification')).toBeVisible();
| ^ Error: expect(locator).toBeVisible() failed
22 | await page.locator('button').filter({ hasText: 'Send WhatsApp OTP' }).click();
23 | await page.locator('input[placeholder="Enter 123456"]').first().fill('123456');
24 | await page.locator('button').filter({ hasText: 'Verify Code' }).first().click();
25 | await expect(page.getByText('✓ Mobile & WhatsApp Verified')).toBeVisible();
26 |
27 | await page.locator('button').filter({ hasText: 'Send Email OTP' }).click();
28 | await page.locator('input[placeholder="Enter 123456"]').last().fill('123456');
29 | await page.locator('button').filter({ hasText: 'Verify Code' }).last().click();
30 | await expect(page.getByText('✓ Email Verified')).toBeVisible();
31 | await page.locator('button').filter({ hasText: 'Next Step: Identity Verification' }).click();
32 |
33 | // 4. Step 2: Tax & Identity Verification
34 | await expect(page.getByText('Step 2 of 3: Tax & Identity Verification')).toBeVisible();
35 | await page.locator('input#verify-gst').clear();
36 | await page.locator('input#verify-gst').fill('29AAAAA1111A1Z1');
37 | await page.locator('button').filter({ hasText: 'Submit GSTIN' }).click();
38 | await expect(page.getByText('verification will be completed within next 24 hrs')).toBeVisible();
39 |
40 | // Upload mock Aadhaar & PAN files
41 | await page.setInputFiles('input#aadhar-upload', {
42 | name: 'aadhar_card.pdf',
43 | mimeType: 'application/pdf',
44 | buffer: Buffer.from('mock aadhaar pdf'),
45 | });
46 | await expect(page.getByText('Selected: aadhar_card.pdf')).toBeVisible();
47 |
48 | await page.setInputFiles('input#pan-upload', {
49 | name: 'pan_card.pdf',
50 | mimeType: 'application/pdf',
51 | buffer: Buffer.from('mock pan pdf'),
52 | });
53 | await expect(page.getByText('Selected: pan_card.pdf')).toBeVisible();
54 |
55 | await page.locator('button').filter({ hasText: 'Next Step: Store & Location' }).click();
56 |
57 | // 5. Step 3: Store & Pickup Location Setup
58 | await expect(page.getByText('Step 3 of 3: Store & Pickup Location')).toBeVisible();
59 | await page.locator('input#store-name').clear();
60 | await page.locator('input#store-name').fill('Teak Wood Craft Store');
61 | await page.locator('textarea#store-bio').clear();
62 | await page.locator('textarea#store-bio').fill('Teak wood hand-carved home decor elements.');
63 |
64 | // Test interactive map coordinate pinning
65 | await expect(page.getByText('Store Location on Map *')).toBeVisible();
66 | const mapGridParent = page.locator('span').filter({ hasText: 'Click anywhere on the map grid to pin location' }).locator('..');
67 | await mapGridParent.click({ position: { x: 100, y: 80 } });
68 | await expect(page.getByText('Coordinates: Lat')).toBeVisible();
69 |
70 | await expect(page.locator('input#location-text')).not.toHaveValue('');
71 | await page.locator('input#loc-city').clear();
72 | await page.locator('input#loc-city').fill('Bangalore');
73 | await page.locator('input#loc-pincode').clear();
74 | await page.locator('input#loc-pincode').fill('560001');
75 | await page.locator('button').filter({ hasText: 'Submit Supplier Profile' }).click();
76 |
77 | // 6. Setup Welcome Tour Stepper
78 | await expect(page.getByText('Supplier Account Under Review ⏳')).toBeVisible();
79 | await page.locator('button').filter({ hasText: 'Start Guided Tour 🎬' }).click();
80 | await expect(page.getByText('📦 Products & Inventory Management')).toBeVisible();
81 | await page.locator('button').filter({ hasText: 'Next: Order Management' }).click();
82 | await expect(page.getByText('🚚 Order Acceptance Control')).toBeVisible();
83 | await page.locator('button').filter({ hasText: 'Next: Barcode Generation' }).click();
84 | await expect(page.getByText('🏷️ Barcode Identification & Tracking')).toBeVisible();
85 | await page.locator('button').filter({ hasText: 'Next: Earnings & Wallet' }).click();
86 | await expect(page.getByText('💼 Wallet & Payout Withdrawals')).toBeVisible();
87 | await page.locator('button').filter({ hasText: 'Explore Dashboard 🚀' }).click();
88 |
89 | // 7. Check Active Dashboard Tab
90 | await expect(page.getByText('Performance Analytics')).toBeVisible();
91 |
92 | // 8. Manage Products tab & Bulk template download
93 | await page.locator('button, a').filter({ hasText: 'Manage Products' }).click();
94 | await expect(page.getByText('Active Inventory')).toBeVisible();
95 |
96 | const downloadPromise = page.waitForEvent('download');
97 | await page.locator('button, a').filter({ hasText: 'Download Sample Excel Template' }).click();
98 | const download = await downloadPromise;
99 | expect(download.suggestedFilename()).toBeDefined();
100 |
101 | // 9. Orders Acceptance Flow
102 | await page.locator('button, a').filter({ hasText: 'Orders & Transit' }).click();
103 | await expect(page.getByText('Active Orders & Payout status')).toBeVisible();
104 | await expect(page.getByText('Pending Acceptance')).toBeVisible();
105 | await page.locator('button').filter({ hasText: 'Accept' }).first().click();
106 | await expect(page.getByText('Ready to Ship')).toBeVisible();
107 |
108 | // 10. Barcode Generator
109 | await page.locator('button, a').filter({ hasText: 'Barcode Generator' }).click();
110 | await expect(page.getByText('Product Barcode Generator')).toBeVisible();
111 | await page.locator('select#barcode-product').selectOption({ index: 1 });
112 | await page.locator('button').filter({ hasText: 'Generate Barcode Graphic' }).click();
113 | await expect(page.getByText('Generated Barcode Preview')).toBeVisible();
114 | await expect(page.getByText('Print Label')).toBeVisible();
115 | await expect(page.getByText('Download SVG')).toBeVisible();
116 | });
117 |
118 | test('enforces security constraints and validation rules (negative test cases)', async ({ page }) => {
119 | // 1. Visit Home and verify dashboard components are not in DOM (route guarding)
120 | await page.goto('/');
121 | await expect(page.locator('.dashboard-container')).toBeHidden();
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

View file

@ -0,0 +1,234 @@
# Instructions
- Following Playwright test failed.
- Explain why, be concise, respect Playwright best practices.
- Provide a snippet of code with the fix, if possible.
# Test info
- Name: onboarding.spec.ts >> Supplier Portal Onboarding & Feature E2E Flow >> enforces security constraints and validation rules (negative test cases)
- Location: playwright/e2e/onboarding.spec.ts:118:3
# Error details
```
Error: expect(locator).toBeVisible() failed
Locator: getByText('Step 1 of 3: Contact Verification')
Expected: visible
Timeout: 5000ms
Error: element(s) not found
Call log:
- Expect "toBeVisible" with timeout 5000ms
- waiting for getByText('Step 1 of 3: Contact Verification')
```
```yaml
- banner:
- text: A Global Artisans Hub
- navigation:
- button "Platform"
- button "Pricing"
- button "Success Stories"
- button "Support"
- button "Login"
- button "Get Started"
- main:
- button "Login"
- button "Register"
- heading "Create Your Supplier Account" [level=2]
- text: Business Email *
- textbox "Business Email *":
- /placeholder: Enter email address
- text: security_test_1786700927306@example.com
- text: Mobile Number *
- textbox "Mobile Number *":
- /placeholder: Enter 10-digit number
- text: "9358500184"
- text: Create Password *
- textbox "Create Password *":
- /placeholder: Minimum 8 characters
- text: Password123!
- button "🙈"
- text: Confirm Password *
- textbox "Confirm Password *":
- /placeholder: Re-enter password
- text: Password123!
- button "🙈"
- checkbox "I accept the Terms of Service and Privacy Policy *" [checked]
- text: I accept the
- link "Terms of Service":
- /url: "#terms"
- text: and
- link "Privacy Policy":
- /url: "#privacy"
- text: "*"
- button "Register Business"
- contentinfo:
- text: Global Artisans Hub
- link "About Us":
- /url: "#about"
- link "Careers":
- /url: "#careers"
- link "Press":
- /url: "#press"
- link "Terms":
- /url: "#terms"
- link "Privacy":
- /url: "#privacy"
- text: © 2026 Global Artisans Hub. All rights reserved.
```
# Test source
```ts
36 | await page.locator('input#verify-gst').fill('29AAAAA1111A1Z1');
37 | await page.locator('button').filter({ hasText: 'Submit GSTIN' }).click();
38 | await expect(page.getByText('verification will be completed within next 24 hrs')).toBeVisible();
39 |
40 | // Upload mock Aadhaar & PAN files
41 | await page.setInputFiles('input#aadhar-upload', {
42 | name: 'aadhar_card.pdf',
43 | mimeType: 'application/pdf',
44 | buffer: Buffer.from('mock aadhaar pdf'),
45 | });
46 | await expect(page.getByText('Selected: aadhar_card.pdf')).toBeVisible();
47 |
48 | await page.setInputFiles('input#pan-upload', {
49 | name: 'pan_card.pdf',
50 | mimeType: 'application/pdf',
51 | buffer: Buffer.from('mock pan pdf'),
52 | });
53 | await expect(page.getByText('Selected: pan_card.pdf')).toBeVisible();
54 |
55 | await page.locator('button').filter({ hasText: 'Next Step: Store & Location' }).click();
56 |
57 | // 5. Step 3: Store & Pickup Location Setup
58 | await expect(page.getByText('Step 3 of 3: Store & Pickup Location')).toBeVisible();
59 | await page.locator('input#store-name').clear();
60 | await page.locator('input#store-name').fill('Teak Wood Craft Store');
61 | await page.locator('textarea#store-bio').clear();
62 | await page.locator('textarea#store-bio').fill('Teak wood hand-carved home decor elements.');
63 |
64 | // Test interactive map coordinate pinning
65 | await expect(page.getByText('Store Location on Map *')).toBeVisible();
66 | const mapGridParent = page.locator('span').filter({ hasText: 'Click anywhere on the map grid to pin location' }).locator('..');
67 | await mapGridParent.click({ position: { x: 100, y: 80 } });
68 | await expect(page.getByText('Coordinates: Lat')).toBeVisible();
69 |
70 | await expect(page.locator('input#location-text')).not.toHaveValue('');
71 | await page.locator('input#loc-city').clear();
72 | await page.locator('input#loc-city').fill('Bangalore');
73 | await page.locator('input#loc-pincode').clear();
74 | await page.locator('input#loc-pincode').fill('560001');
75 | await page.locator('button').filter({ hasText: 'Submit Supplier Profile' }).click();
76 |
77 | // 6. Setup Welcome Tour Stepper
78 | await expect(page.getByText('Supplier Account Under Review ⏳')).toBeVisible();
79 | await page.locator('button').filter({ hasText: 'Start Guided Tour 🎬' }).click();
80 | await expect(page.getByText('📦 Products & Inventory Management')).toBeVisible();
81 | await page.locator('button').filter({ hasText: 'Next: Order Management' }).click();
82 | await expect(page.getByText('🚚 Order Acceptance Control')).toBeVisible();
83 | await page.locator('button').filter({ hasText: 'Next: Barcode Generation' }).click();
84 | await expect(page.getByText('🏷️ Barcode Identification & Tracking')).toBeVisible();
85 | await page.locator('button').filter({ hasText: 'Next: Earnings & Wallet' }).click();
86 | await expect(page.getByText('💼 Wallet & Payout Withdrawals')).toBeVisible();
87 | await page.locator('button').filter({ hasText: 'Explore Dashboard 🚀' }).click();
88 |
89 | // 7. Check Active Dashboard Tab
90 | await expect(page.getByText('Performance Analytics')).toBeVisible();
91 |
92 | // 8. Manage Products tab & Bulk template download
93 | await page.locator('button, a').filter({ hasText: 'Manage Products' }).click();
94 | await expect(page.getByText('Active Inventory')).toBeVisible();
95 |
96 | const downloadPromise = page.waitForEvent('download');
97 | await page.locator('button, a').filter({ hasText: 'Download Sample Excel Template' }).click();
98 | const download = await downloadPromise;
99 | expect(download.suggestedFilename()).toBeDefined();
100 |
101 | // 9. Orders Acceptance Flow
102 | await page.locator('button, a').filter({ hasText: 'Orders & Transit' }).click();
103 | await expect(page.getByText('Active Orders & Payout status')).toBeVisible();
104 | await expect(page.getByText('Pending Acceptance')).toBeVisible();
105 | await page.locator('button').filter({ hasText: 'Accept' }).first().click();
106 | await expect(page.getByText('Ready to Ship')).toBeVisible();
107 |
108 | // 10. Barcode Generator
109 | await page.locator('button, a').filter({ hasText: 'Barcode Generator' }).click();
110 | await expect(page.getByText('Product Barcode Generator')).toBeVisible();
111 | await page.locator('select#barcode-product').selectOption({ index: 1 });
112 | await page.locator('button').filter({ hasText: 'Generate Barcode Graphic' }).click();
113 | await expect(page.getByText('Generated Barcode Preview')).toBeVisible();
114 | await expect(page.getByText('Print Label')).toBeVisible();
115 | await expect(page.getByText('Download SVG')).toBeVisible();
116 | });
117 |
118 | test('enforces security constraints and validation rules (negative test cases)', async ({ page }) => {
119 | // 1. Visit Home and verify dashboard components are not in DOM (route guarding)
120 | await page.goto('/');
121 | await expect(page.locator('.dashboard-container')).toBeHidden();
122 | await expect(page.locator('.sidebar-menu')).toBeHidden();
123 |
124 | // 2. Go to Registration
125 | await page.locator('button, a').filter({ hasText: 'Get Started Today' }).first().click();
126 | const randSecurityUser = `security_test_${Date.now()}@example.com`;
127 | const randSecurityPhone = `9${Math.floor(100000000 + Math.random() * 900000000)}`;
128 | await page.locator('input#reg-email').fill(randSecurityUser);
129 | await page.locator('input#reg-phone').fill(randSecurityPhone);
130 | await page.locator('input#reg-pass').fill('Password123!');
131 | await page.locator('input#reg-confirm-pass').fill('Password123!');
132 | await page.locator('input#reg-policy').check();
133 | await page.locator('button').filter({ hasText: 'Register Business' }).click();
134 |
135 | // 3. Step 1: Negative OTP validations
> 136 | await expect(page.getByText('Step 1 of 3: Contact Verification')).toBeVisible();
| ^ Error: expect(locator).toBeVisible() failed
137 |
138 | // Proceed button must be disabled initially
139 | await expect(page.locator('button').filter({ hasText: 'Next Step: Identity Verification' })).toBeDisabled();
140 |
141 | // Submit invalid WhatsApp OTP
142 | await page.locator('button').filter({ hasText: 'Send WhatsApp OTP' }).click();
143 | await page.locator('input[placeholder="Enter 123456"]').first().fill('000000');
144 |
145 | // Capture dialog
146 | let alertMessage = '';
147 | page.once('dialog', async dialog => {
148 | alertMessage = dialog.message();
149 | await dialog.accept();
150 | });
151 |
152 | await page.locator('button').filter({ hasText: 'Verify Code' }).first().click();
153 |
154 | // Give brief time/event loop ticks to ensure dialog handler fires
155 | await page.waitForTimeout(500);
156 | expect(alertMessage).toBe('Incorrect code. Enter 123456');
157 | await expect(page.getByText('✓ Mobile & WhatsApp Verified')).toBeHidden();
158 |
159 | // Correct the code to enable proceed
160 | await page.locator('input[placeholder="Enter 123456"]').first().clear();
161 | await page.locator('input[placeholder="Enter 123456"]').first().fill('123456');
162 | await page.locator('button').filter({ hasText: 'Verify Code' }).first().click();
163 | await expect(page.getByText('✓ Mobile & WhatsApp Verified')).toBeVisible();
164 |
165 | // Submit invalid Email OTP
166 | await page.locator('button').filter({ hasText: 'Send Email OTP' }).click();
167 | await page.locator('input[placeholder="Enter 123456"]').last().fill('999999');
168 |
169 | page.once('dialog', async dialog => {
170 | alertMessage = dialog.message();
171 | await dialog.accept();
172 | });
173 |
174 | await page.locator('button').filter({ hasText: 'Verify Code' }).last().click();
175 | await page.waitForTimeout(500);
176 | expect(alertMessage).toBe('Incorrect code. Enter 123456');
177 | await expect(page.getByText('✓ Email Verified')).toBeHidden();
178 | await expect(page.locator('button').filter({ hasText: 'Next Step: Identity Verification' })).toBeDisabled();
179 | });
180 | });
181 |
```

File diff suppressed because one or more lines are too long

30
playwright.config.ts Normal file
View file

@ -0,0 +1,30 @@
import { defineConfig, devices } from '@playwright/test';
export default defineConfig({
testDir: './playwright/e2e',
fullyParallel: true,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 0,
workers: process.env.CI ? 1 : undefined,
reporter: 'html',
use: {
baseURL: 'https://betasuppliers.tipro.in/',
trace: 'on-first-retry',
screenshot: 'only-on-failure',
video: 'retain-on-failure',
},
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
},
{
name: 'firefox',
use: { ...devices['Desktop Firefox'] },
},
{
name: 'webkit',
use: { ...devices['Desktop Safari'] },
},
],
});

View file

@ -0,0 +1,180 @@
import { test, expect } from '@playwright/test';
test.describe('Supplier Portal Onboarding & Feature E2E Flow', () => {
test('completes the registration, contact verification, document upload, location pinning, welcome tour, order acceptance, and barcode generation', async ({ page }) => {
// 1. Visit Landing Page
await page.goto('/');
await expect(page.getByText('Sell Globally.')).toBeVisible();
// 2. Registration Page
await page.locator('button, a').filter({ hasText: 'Get Started Today' }).first().click();
const randUser = `test_seller_${Date.now()}@example.com`;
const randPhone = `9${Math.floor(100000000 + Math.random() * 900000000)}`;
await page.locator('input#reg-email').fill(randUser);
await page.locator('input#reg-phone').fill(randPhone);
await page.locator('input#reg-pass').fill('Super_secure_pass_123!');
await page.locator('input#reg-confirm-pass').fill('Super_secure_pass_123!');
await page.locator('input#reg-policy').check();
await page.locator('button').filter({ hasText: 'Register Business' }).click();
// 3. Step 1: Contact Verification
await expect(page.getByText('Step 1 of 3: Contact Verification')).toBeVisible();
await page.locator('button').filter({ hasText: 'Send WhatsApp OTP' }).click();
await page.locator('input[placeholder="Enter 123456"]').first().fill('123456');
await page.locator('button').filter({ hasText: 'Verify Code' }).first().click();
await expect(page.getByText('✓ Mobile & WhatsApp Verified')).toBeVisible();
await page.locator('button').filter({ hasText: 'Send Email OTP' }).click();
await page.locator('input[placeholder="Enter 123456"]').last().fill('123456');
await page.locator('button').filter({ hasText: 'Verify Code' }).last().click();
await expect(page.getByText('✓ Email Verified')).toBeVisible();
await page.locator('button').filter({ hasText: 'Next Step: Identity Verification' }).click();
// 4. Step 2: Tax & Identity Verification
await expect(page.getByText('Step 2 of 3: Tax & Identity Verification')).toBeVisible();
await page.locator('input#verify-gst').clear();
await page.locator('input#verify-gst').fill('29AAAAA1111A1Z1');
await page.locator('button').filter({ hasText: 'Submit GSTIN' }).click();
await expect(page.getByText('verification will be completed within next 24 hrs')).toBeVisible();
// Upload mock Aadhaar & PAN files
await page.setInputFiles('input#aadhar-upload', {
name: 'aadhar_card.pdf',
mimeType: 'application/pdf',
buffer: Buffer.from('mock aadhaar pdf'),
});
await expect(page.getByText('Selected: aadhar_card.pdf')).toBeVisible();
await page.setInputFiles('input#pan-upload', {
name: 'pan_card.pdf',
mimeType: 'application/pdf',
buffer: Buffer.from('mock pan pdf'),
});
await expect(page.getByText('Selected: pan_card.pdf')).toBeVisible();
await page.locator('button').filter({ hasText: 'Next Step: Store & Location' }).click();
// 5. Step 3: Store & Pickup Location Setup
await expect(page.getByText('Step 3 of 3: Store & Pickup Location')).toBeVisible();
await page.locator('input#store-name').clear();
await page.locator('input#store-name').fill('Teak Wood Craft Store');
await page.locator('textarea#store-bio').clear();
await page.locator('textarea#store-bio').fill('Teak wood hand-carved home decor elements.');
// Test interactive map coordinate pinning
await expect(page.getByText('Store Location on Map *')).toBeVisible();
const mapGridParent = page.locator('span').filter({ hasText: 'Click anywhere on the map grid to pin location' }).locator('..');
await mapGridParent.click({ position: { x: 100, y: 80 } });
await expect(page.getByText('Coordinates: Lat')).toBeVisible();
await expect(page.locator('input#location-text')).not.toHaveValue('');
await page.locator('input#loc-city').clear();
await page.locator('input#loc-city').fill('Bangalore');
await page.locator('input#loc-pincode').clear();
await page.locator('input#loc-pincode').fill('560001');
await page.locator('button').filter({ hasText: 'Submit Supplier Profile' }).click();
// 6. Setup Welcome Tour Stepper
await expect(page.getByText('Supplier Account Under Review ⏳')).toBeVisible();
await page.locator('button').filter({ hasText: 'Start Guided Tour 🎬' }).click();
await expect(page.getByText('📦 Products & Inventory Management')).toBeVisible();
await page.locator('button').filter({ hasText: 'Next: Order Management' }).click();
await expect(page.getByText('🚚 Order Acceptance Control')).toBeVisible();
await page.locator('button').filter({ hasText: 'Next: Barcode Generation' }).click();
await expect(page.getByText('🏷️ Barcode Identification & Tracking')).toBeVisible();
await page.locator('button').filter({ hasText: 'Next: Earnings & Wallet' }).click();
await expect(page.getByText('💼 Wallet & Payout Withdrawals')).toBeVisible();
await page.locator('button').filter({ hasText: 'Explore Dashboard 🚀' }).click();
// 7. Check Active Dashboard Tab
await expect(page.getByText('Performance Analytics')).toBeVisible();
// 8. Manage Products tab & Bulk template download
await page.locator('button, a').filter({ hasText: 'Manage Products' }).click();
await expect(page.getByText('Active Inventory')).toBeVisible();
const downloadPromise = page.waitForEvent('download');
await page.locator('button, a').filter({ hasText: 'Download Sample Excel Template' }).click();
const download = await downloadPromise;
expect(download.suggestedFilename()).toBeDefined();
// 9. Orders Acceptance Flow
await page.locator('button, a').filter({ hasText: 'Orders & Transit' }).click();
await expect(page.getByText('Active Orders & Payout status')).toBeVisible();
await expect(page.getByText('Pending Acceptance')).toBeVisible();
await page.locator('button').filter({ hasText: 'Accept' }).first().click();
await expect(page.getByText('Ready to Ship')).toBeVisible();
// 10. Barcode Generator
await page.locator('button, a').filter({ hasText: 'Barcode Generator' }).click();
await expect(page.getByText('Product Barcode Generator')).toBeVisible();
await page.locator('select#barcode-product').selectOption({ index: 1 });
await page.locator('button').filter({ hasText: 'Generate Barcode Graphic' }).click();
await expect(page.getByText('Generated Barcode Preview')).toBeVisible();
await expect(page.getByText('Print Label')).toBeVisible();
await expect(page.getByText('Download SVG')).toBeVisible();
});
test('enforces security constraints and validation rules (negative test cases)', async ({ page }) => {
// 1. Visit Home and verify dashboard components are not in DOM (route guarding)
await page.goto('/');
await expect(page.locator('.dashboard-container')).toBeHidden();
await expect(page.locator('.sidebar-menu')).toBeHidden();
// 2. Go to Registration
await page.locator('button, a').filter({ hasText: 'Get Started Today' }).first().click();
const randSecurityUser = `security_test_${Date.now()}@example.com`;
const randSecurityPhone = `9${Math.floor(100000000 + Math.random() * 900000000)}`;
await page.locator('input#reg-email').fill(randSecurityUser);
await page.locator('input#reg-phone').fill(randSecurityPhone);
await page.locator('input#reg-pass').fill('Password123!');
await page.locator('input#reg-confirm-pass').fill('Password123!');
await page.locator('input#reg-policy').check();
await page.locator('button').filter({ hasText: 'Register Business' }).click();
// 3. Step 1: Negative OTP validations
await expect(page.getByText('Step 1 of 3: Contact Verification')).toBeVisible();
// Proceed button must be disabled initially
await expect(page.locator('button').filter({ hasText: 'Next Step: Identity Verification' })).toBeDisabled();
// Submit invalid WhatsApp OTP
await page.locator('button').filter({ hasText: 'Send WhatsApp OTP' }).click();
await page.locator('input[placeholder="Enter 123456"]').first().fill('000000');
// Capture dialog
let alertMessage = '';
page.once('dialog', async dialog => {
alertMessage = dialog.message();
await dialog.accept();
});
await page.locator('button').filter({ hasText: 'Verify Code' }).first().click();
// Give brief time/event loop ticks to ensure dialog handler fires
await page.waitForTimeout(500);
expect(alertMessage).toBe('Incorrect code. Enter 123456');
await expect(page.getByText('✓ Mobile & WhatsApp Verified')).toBeHidden();
// Correct the code to enable proceed
await page.locator('input[placeholder="Enter 123456"]').first().clear();
await page.locator('input[placeholder="Enter 123456"]').first().fill('123456');
await page.locator('button').filter({ hasText: 'Verify Code' }).first().click();
await expect(page.getByText('✓ Mobile & WhatsApp Verified')).toBeVisible();
// Submit invalid Email OTP
await page.locator('button').filter({ hasText: 'Send Email OTP' }).click();
await page.locator('input[placeholder="Enter 123456"]').last().fill('999999');
page.once('dialog', async dialog => {
alertMessage = dialog.message();
await dialog.accept();
});
await page.locator('button').filter({ hasText: 'Verify Code' }).last().click();
await page.waitForTimeout(500);
expect(alertMessage).toBe('Incorrect code. Enter 123456');
await expect(page.getByText('✓ Email Verified')).toBeHidden();
await expect(page.locator('button').filter({ hasText: 'Next Step: Identity Verification' })).toBeDisabled();
});
});

View file

@ -0,0 +1,7 @@
{
"status": "failed",
"failedTests": [
"fe534f0825407f213faa-eae28aa470cee3dd351a",
"fe534f0825407f213faa-178b974dec5b4368ccdd"
]
}

View file

@ -0,0 +1,234 @@
# Instructions
- Following Playwright test failed.
- Explain why, be concise, respect Playwright best practices.
- Provide a snippet of code with the fix, if possible.
# Test info
- Name: onboarding.spec.ts >> Supplier Portal Onboarding & Feature E2E Flow >> enforces security constraints and validation rules (negative test cases)
- Location: playwright/e2e/onboarding.spec.ts:118:3
# Error details
```
Error: expect(locator).toBeVisible() failed
Locator: getByText('Step 1 of 3: Contact Verification')
Expected: visible
Timeout: 5000ms
Error: element(s) not found
Call log:
- Expect "toBeVisible" with timeout 5000ms
- waiting for getByText('Step 1 of 3: Contact Verification')
```
```yaml
- banner:
- text: A Global Artisans Hub
- navigation:
- button "Platform"
- button "Pricing"
- button "Success Stories"
- button "Support"
- button "Login"
- button "Get Started"
- main:
- button "Login"
- button "Register"
- heading "Create Your Supplier Account" [level=2]
- text: Business Email *
- textbox "Business Email *":
- /placeholder: Enter email address
- text: security_test_1786700927306@example.com
- text: Mobile Number *
- textbox "Mobile Number *":
- /placeholder: Enter 10-digit number
- text: "9358500184"
- text: Create Password *
- textbox "Create Password *":
- /placeholder: Minimum 8 characters
- text: Password123!
- button "🙈"
- text: Confirm Password *
- textbox "Confirm Password *":
- /placeholder: Re-enter password
- text: Password123!
- button "🙈"
- checkbox "I accept the Terms of Service and Privacy Policy *" [checked]
- text: I accept the
- link "Terms of Service":
- /url: "#terms"
- text: and
- link "Privacy Policy":
- /url: "#privacy"
- text: "*"
- button "Register Business"
- contentinfo:
- text: Global Artisans Hub
- link "About Us":
- /url: "#about"
- link "Careers":
- /url: "#careers"
- link "Press":
- /url: "#press"
- link "Terms":
- /url: "#terms"
- link "Privacy":
- /url: "#privacy"
- text: © 2026 Global Artisans Hub. All rights reserved.
```
# Test source
```ts
36 | await page.locator('input#verify-gst').fill('29AAAAA1111A1Z1');
37 | await page.locator('button').filter({ hasText: 'Submit GSTIN' }).click();
38 | await expect(page.getByText('verification will be completed within next 24 hrs')).toBeVisible();
39 |
40 | // Upload mock Aadhaar & PAN files
41 | await page.setInputFiles('input#aadhar-upload', {
42 | name: 'aadhar_card.pdf',
43 | mimeType: 'application/pdf',
44 | buffer: Buffer.from('mock aadhaar pdf'),
45 | });
46 | await expect(page.getByText('Selected: aadhar_card.pdf')).toBeVisible();
47 |
48 | await page.setInputFiles('input#pan-upload', {
49 | name: 'pan_card.pdf',
50 | mimeType: 'application/pdf',
51 | buffer: Buffer.from('mock pan pdf'),
52 | });
53 | await expect(page.getByText('Selected: pan_card.pdf')).toBeVisible();
54 |
55 | await page.locator('button').filter({ hasText: 'Next Step: Store & Location' }).click();
56 |
57 | // 5. Step 3: Store & Pickup Location Setup
58 | await expect(page.getByText('Step 3 of 3: Store & Pickup Location')).toBeVisible();
59 | await page.locator('input#store-name').clear();
60 | await page.locator('input#store-name').fill('Teak Wood Craft Store');
61 | await page.locator('textarea#store-bio').clear();
62 | await page.locator('textarea#store-bio').fill('Teak wood hand-carved home decor elements.');
63 |
64 | // Test interactive map coordinate pinning
65 | await expect(page.getByText('Store Location on Map *')).toBeVisible();
66 | const mapGridParent = page.locator('span').filter({ hasText: 'Click anywhere on the map grid to pin location' }).locator('..');
67 | await mapGridParent.click({ position: { x: 100, y: 80 } });
68 | await expect(page.getByText('Coordinates: Lat')).toBeVisible();
69 |
70 | await expect(page.locator('input#location-text')).not.toHaveValue('');
71 | await page.locator('input#loc-city').clear();
72 | await page.locator('input#loc-city').fill('Bangalore');
73 | await page.locator('input#loc-pincode').clear();
74 | await page.locator('input#loc-pincode').fill('560001');
75 | await page.locator('button').filter({ hasText: 'Submit Supplier Profile' }).click();
76 |
77 | // 6. Setup Welcome Tour Stepper
78 | await expect(page.getByText('Supplier Account Under Review ⏳')).toBeVisible();
79 | await page.locator('button').filter({ hasText: 'Start Guided Tour 🎬' }).click();
80 | await expect(page.getByText('📦 Products & Inventory Management')).toBeVisible();
81 | await page.locator('button').filter({ hasText: 'Next: Order Management' }).click();
82 | await expect(page.getByText('🚚 Order Acceptance Control')).toBeVisible();
83 | await page.locator('button').filter({ hasText: 'Next: Barcode Generation' }).click();
84 | await expect(page.getByText('🏷️ Barcode Identification & Tracking')).toBeVisible();
85 | await page.locator('button').filter({ hasText: 'Next: Earnings & Wallet' }).click();
86 | await expect(page.getByText('💼 Wallet & Payout Withdrawals')).toBeVisible();
87 | await page.locator('button').filter({ hasText: 'Explore Dashboard 🚀' }).click();
88 |
89 | // 7. Check Active Dashboard Tab
90 | await expect(page.getByText('Performance Analytics')).toBeVisible();
91 |
92 | // 8. Manage Products tab & Bulk template download
93 | await page.locator('button, a').filter({ hasText: 'Manage Products' }).click();
94 | await expect(page.getByText('Active Inventory')).toBeVisible();
95 |
96 | const downloadPromise = page.waitForEvent('download');
97 | await page.locator('button, a').filter({ hasText: 'Download Sample Excel Template' }).click();
98 | const download = await downloadPromise;
99 | expect(download.suggestedFilename()).toBeDefined();
100 |
101 | // 9. Orders Acceptance Flow
102 | await page.locator('button, a').filter({ hasText: 'Orders & Transit' }).click();
103 | await expect(page.getByText('Active Orders & Payout status')).toBeVisible();
104 | await expect(page.getByText('Pending Acceptance')).toBeVisible();
105 | await page.locator('button').filter({ hasText: 'Accept' }).first().click();
106 | await expect(page.getByText('Ready to Ship')).toBeVisible();
107 |
108 | // 10. Barcode Generator
109 | await page.locator('button, a').filter({ hasText: 'Barcode Generator' }).click();
110 | await expect(page.getByText('Product Barcode Generator')).toBeVisible();
111 | await page.locator('select#barcode-product').selectOption({ index: 1 });
112 | await page.locator('button').filter({ hasText: 'Generate Barcode Graphic' }).click();
113 | await expect(page.getByText('Generated Barcode Preview')).toBeVisible();
114 | await expect(page.getByText('Print Label')).toBeVisible();
115 | await expect(page.getByText('Download SVG')).toBeVisible();
116 | });
117 |
118 | test('enforces security constraints and validation rules (negative test cases)', async ({ page }) => {
119 | // 1. Visit Home and verify dashboard components are not in DOM (route guarding)
120 | await page.goto('/');
121 | await expect(page.locator('.dashboard-container')).toBeHidden();
122 | await expect(page.locator('.sidebar-menu')).toBeHidden();
123 |
124 | // 2. Go to Registration
125 | await page.locator('button, a').filter({ hasText: 'Get Started Today' }).first().click();
126 | const randSecurityUser = `security_test_${Date.now()}@example.com`;
127 | const randSecurityPhone = `9${Math.floor(100000000 + Math.random() * 900000000)}`;
128 | await page.locator('input#reg-email').fill(randSecurityUser);
129 | await page.locator('input#reg-phone').fill(randSecurityPhone);
130 | await page.locator('input#reg-pass').fill('Password123!');
131 | await page.locator('input#reg-confirm-pass').fill('Password123!');
132 | await page.locator('input#reg-policy').check();
133 | await page.locator('button').filter({ hasText: 'Register Business' }).click();
134 |
135 | // 3. Step 1: Negative OTP validations
> 136 | await expect(page.getByText('Step 1 of 3: Contact Verification')).toBeVisible();
| ^ Error: expect(locator).toBeVisible() failed
137 |
138 | // Proceed button must be disabled initially
139 | await expect(page.locator('button').filter({ hasText: 'Next Step: Identity Verification' })).toBeDisabled();
140 |
141 | // Submit invalid WhatsApp OTP
142 | await page.locator('button').filter({ hasText: 'Send WhatsApp OTP' }).click();
143 | await page.locator('input[placeholder="Enter 123456"]').first().fill('000000');
144 |
145 | // Capture dialog
146 | let alertMessage = '';
147 | page.once('dialog', async dialog => {
148 | alertMessage = dialog.message();
149 | await dialog.accept();
150 | });
151 |
152 | await page.locator('button').filter({ hasText: 'Verify Code' }).first().click();
153 |
154 | // Give brief time/event loop ticks to ensure dialog handler fires
155 | await page.waitForTimeout(500);
156 | expect(alertMessage).toBe('Incorrect code. Enter 123456');
157 | await expect(page.getByText('✓ Mobile & WhatsApp Verified')).toBeHidden();
158 |
159 | // Correct the code to enable proceed
160 | await page.locator('input[placeholder="Enter 123456"]').first().clear();
161 | await page.locator('input[placeholder="Enter 123456"]').first().fill('123456');
162 | await page.locator('button').filter({ hasText: 'Verify Code' }).first().click();
163 | await expect(page.getByText('✓ Mobile & WhatsApp Verified')).toBeVisible();
164 |
165 | // Submit invalid Email OTP
166 | await page.locator('button').filter({ hasText: 'Send Email OTP' }).click();
167 | await page.locator('input[placeholder="Enter 123456"]').last().fill('999999');
168 |
169 | page.once('dialog', async dialog => {
170 | alertMessage = dialog.message();
171 | await dialog.accept();
172 | });
173 |
174 | await page.locator('button').filter({ hasText: 'Verify Code' }).last().click();
175 | await page.waitForTimeout(500);
176 | expect(alertMessage).toBe('Incorrect code. Enter 123456');
177 | await expect(page.getByText('✓ Email Verified')).toBeHidden();
178 | await expect(page.locator('button').filter({ hasText: 'Next Step: Identity Verification' })).toBeDisabled();
179 | });
180 | });
181 |
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

View file

@ -0,0 +1,209 @@
# Instructions
- Following Playwright test failed.
- Explain why, be concise, respect Playwright best practices.
- Provide a snippet of code with the fix, if possible.
# Test info
- Name: onboarding.spec.ts >> Supplier Portal Onboarding & Feature E2E Flow >> completes the registration, contact verification, document upload, location pinning, welcome tour, order acceptance, and barcode generation
- Location: playwright/e2e/onboarding.spec.ts:4:3
# Error details
```
Error: expect(locator).toBeVisible() failed
Locator: getByText('Step 1 of 3: Contact Verification')
Expected: visible
Timeout: 5000ms
Error: element(s) not found
Call log:
- Expect "toBeVisible" with timeout 5000ms
- waiting for getByText('Step 1 of 3: Contact Verification')
```
```yaml
- banner:
- text: A Global Artisans Hub
- navigation:
- button "Platform"
- button "Pricing"
- button "Success Stories"
- button "Support"
- button "Login"
- button "Get Started"
- main:
- button "Login"
- button "Register"
- heading "Create Your Supplier Account" [level=2]
- text: Business Email *
- textbox "Business Email *":
- /placeholder: Enter email address
- text: test_seller_1786700927358@example.com
- text: Mobile Number *
- textbox "Mobile Number *":
- /placeholder: Enter 10-digit number
- text: "9118192284"
- text: Create Password *
- textbox "Create Password *":
- /placeholder: Minimum 8 characters
- text: Super_secure_pass_123!
- button "🙈"
- text: Confirm Password *
- textbox "Confirm Password *":
- /placeholder: Re-enter password
- text: Super_secure_pass_123!
- button "🙈"
- checkbox "I accept the Terms of Service and Privacy Policy *" [checked]
- text: I accept the
- link "Terms of Service":
- /url: "#terms"
- text: and
- link "Privacy Policy":
- /url: "#privacy"
- text: "*"
- button "Register Business"
- contentinfo:
- text: Global Artisans Hub
- link "About Us":
- /url: "#about"
- link "Careers":
- /url: "#careers"
- link "Press":
- /url: "#press"
- link "Terms":
- /url: "#terms"
- link "Privacy":
- /url: "#privacy"
- text: © 2026 Global Artisans Hub. All rights reserved.
```
# Test source
```ts
1 | import { test, expect } from '@playwright/test';
2 |
3 | test.describe('Supplier Portal Onboarding & Feature E2E Flow', () => {
4 | test('completes the registration, contact verification, document upload, location pinning, welcome tour, order acceptance, and barcode generation', async ({ page }) => {
5 | // 1. Visit Landing Page
6 | await page.goto('/');
7 | await expect(page.getByText('Sell Globally.')).toBeVisible();
8 |
9 | // 2. Registration Page
10 | await page.locator('button, a').filter({ hasText: 'Get Started Today' }).first().click();
11 | const randUser = `test_seller_${Date.now()}@example.com`;
12 | const randPhone = `9${Math.floor(100000000 + Math.random() * 900000000)}`;
13 | await page.locator('input#reg-email').fill(randUser);
14 | await page.locator('input#reg-phone').fill(randPhone);
15 | await page.locator('input#reg-pass').fill('Super_secure_pass_123!');
16 | await page.locator('input#reg-confirm-pass').fill('Super_secure_pass_123!');
17 | await page.locator('input#reg-policy').check();
18 | await page.locator('button').filter({ hasText: 'Register Business' }).click();
19 |
20 | // 3. Step 1: Contact Verification
> 21 | await expect(page.getByText('Step 1 of 3: Contact Verification')).toBeVisible();
| ^ Error: expect(locator).toBeVisible() failed
22 | await page.locator('button').filter({ hasText: 'Send WhatsApp OTP' }).click();
23 | await page.locator('input[placeholder="Enter 123456"]').first().fill('123456');
24 | await page.locator('button').filter({ hasText: 'Verify Code' }).first().click();
25 | await expect(page.getByText('✓ Mobile & WhatsApp Verified')).toBeVisible();
26 |
27 | await page.locator('button').filter({ hasText: 'Send Email OTP' }).click();
28 | await page.locator('input[placeholder="Enter 123456"]').last().fill('123456');
29 | await page.locator('button').filter({ hasText: 'Verify Code' }).last().click();
30 | await expect(page.getByText('✓ Email Verified')).toBeVisible();
31 | await page.locator('button').filter({ hasText: 'Next Step: Identity Verification' }).click();
32 |
33 | // 4. Step 2: Tax & Identity Verification
34 | await expect(page.getByText('Step 2 of 3: Tax & Identity Verification')).toBeVisible();
35 | await page.locator('input#verify-gst').clear();
36 | await page.locator('input#verify-gst').fill('29AAAAA1111A1Z1');
37 | await page.locator('button').filter({ hasText: 'Submit GSTIN' }).click();
38 | await expect(page.getByText('verification will be completed within next 24 hrs')).toBeVisible();
39 |
40 | // Upload mock Aadhaar & PAN files
41 | await page.setInputFiles('input#aadhar-upload', {
42 | name: 'aadhar_card.pdf',
43 | mimeType: 'application/pdf',
44 | buffer: Buffer.from('mock aadhaar pdf'),
45 | });
46 | await expect(page.getByText('Selected: aadhar_card.pdf')).toBeVisible();
47 |
48 | await page.setInputFiles('input#pan-upload', {
49 | name: 'pan_card.pdf',
50 | mimeType: 'application/pdf',
51 | buffer: Buffer.from('mock pan pdf'),
52 | });
53 | await expect(page.getByText('Selected: pan_card.pdf')).toBeVisible();
54 |
55 | await page.locator('button').filter({ hasText: 'Next Step: Store & Location' }).click();
56 |
57 | // 5. Step 3: Store & Pickup Location Setup
58 | await expect(page.getByText('Step 3 of 3: Store & Pickup Location')).toBeVisible();
59 | await page.locator('input#store-name').clear();
60 | await page.locator('input#store-name').fill('Teak Wood Craft Store');
61 | await page.locator('textarea#store-bio').clear();
62 | await page.locator('textarea#store-bio').fill('Teak wood hand-carved home decor elements.');
63 |
64 | // Test interactive map coordinate pinning
65 | await expect(page.getByText('Store Location on Map *')).toBeVisible();
66 | const mapGridParent = page.locator('span').filter({ hasText: 'Click anywhere on the map grid to pin location' }).locator('..');
67 | await mapGridParent.click({ position: { x: 100, y: 80 } });
68 | await expect(page.getByText('Coordinates: Lat')).toBeVisible();
69 |
70 | await expect(page.locator('input#location-text')).not.toHaveValue('');
71 | await page.locator('input#loc-city').clear();
72 | await page.locator('input#loc-city').fill('Bangalore');
73 | await page.locator('input#loc-pincode').clear();
74 | await page.locator('input#loc-pincode').fill('560001');
75 | await page.locator('button').filter({ hasText: 'Submit Supplier Profile' }).click();
76 |
77 | // 6. Setup Welcome Tour Stepper
78 | await expect(page.getByText('Supplier Account Under Review ⏳')).toBeVisible();
79 | await page.locator('button').filter({ hasText: 'Start Guided Tour 🎬' }).click();
80 | await expect(page.getByText('📦 Products & Inventory Management')).toBeVisible();
81 | await page.locator('button').filter({ hasText: 'Next: Order Management' }).click();
82 | await expect(page.getByText('🚚 Order Acceptance Control')).toBeVisible();
83 | await page.locator('button').filter({ hasText: 'Next: Barcode Generation' }).click();
84 | await expect(page.getByText('🏷️ Barcode Identification & Tracking')).toBeVisible();
85 | await page.locator('button').filter({ hasText: 'Next: Earnings & Wallet' }).click();
86 | await expect(page.getByText('💼 Wallet & Payout Withdrawals')).toBeVisible();
87 | await page.locator('button').filter({ hasText: 'Explore Dashboard 🚀' }).click();
88 |
89 | // 7. Check Active Dashboard Tab
90 | await expect(page.getByText('Performance Analytics')).toBeVisible();
91 |
92 | // 8. Manage Products tab & Bulk template download
93 | await page.locator('button, a').filter({ hasText: 'Manage Products' }).click();
94 | await expect(page.getByText('Active Inventory')).toBeVisible();
95 |
96 | const downloadPromise = page.waitForEvent('download');
97 | await page.locator('button, a').filter({ hasText: 'Download Sample Excel Template' }).click();
98 | const download = await downloadPromise;
99 | expect(download.suggestedFilename()).toBeDefined();
100 |
101 | // 9. Orders Acceptance Flow
102 | await page.locator('button, a').filter({ hasText: 'Orders & Transit' }).click();
103 | await expect(page.getByText('Active Orders & Payout status')).toBeVisible();
104 | await expect(page.getByText('Pending Acceptance')).toBeVisible();
105 | await page.locator('button').filter({ hasText: 'Accept' }).first().click();
106 | await expect(page.getByText('Ready to Ship')).toBeVisible();
107 |
108 | // 10. Barcode Generator
109 | await page.locator('button, a').filter({ hasText: 'Barcode Generator' }).click();
110 | await expect(page.getByText('Product Barcode Generator')).toBeVisible();
111 | await page.locator('select#barcode-product').selectOption({ index: 1 });
112 | await page.locator('button').filter({ hasText: 'Generate Barcode Graphic' }).click();
113 | await expect(page.getByText('Generated Barcode Preview')).toBeVisible();
114 | await expect(page.getByText('Print Label')).toBeVisible();
115 | await expect(page.getByText('Download SVG')).toBeVisible();
116 | });
117 |
118 | test('enforces security constraints and validation rules (negative test cases)', async ({ page }) => {
119 | // 1. Visit Home and verify dashboard components are not in DOM (route guarding)
120 | await page.goto('/');
121 | await expect(page.locator('.dashboard-container')).toBeHidden();
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB