fixing issue
This commit is contained in:
parent
dfdbf2b1d5
commit
f92211ff43
9 changed files with 3 additions and 505 deletions
|
|
@ -1,250 +0,0 @@
|
||||||
# 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('Shipping Label Preview')
|
|
||||||
Expected: visible
|
|
||||||
Timeout: 5000ms
|
|
||||||
Error: element(s) not found
|
|
||||||
|
|
||||||
Call log:
|
|
||||||
- Expect "toBeVisible" with timeout 5000ms
|
|
||||||
- waiting for getByText('Shipping Label Preview')
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
- banner:
|
|
||||||
- text: A Global Artisans Hub
|
|
||||||
- navigation:
|
|
||||||
- button "Platform"
|
|
||||||
- button "Pricing"
|
|
||||||
- button "Success Stories"
|
|
||||||
- button "Support"
|
|
||||||
- button "Logout"
|
|
||||||
- complementary:
|
|
||||||
- text: SELLER PANEL
|
|
||||||
- heading "Teak Wood Craft Store" [level=4]
|
|
||||||
- list:
|
|
||||||
- listitem:
|
|
||||||
- button "📊 Overview & Analytics"
|
|
||||||
- listitem:
|
|
||||||
- button "📦 Manage Products"
|
|
||||||
- listitem:
|
|
||||||
- button "🚚 Orders & Transit"
|
|
||||||
- listitem:
|
|
||||||
- button "🔄 Returns Management"
|
|
||||||
- listitem:
|
|
||||||
- button "💼 Wallet & Payouts"
|
|
||||||
- listitem:
|
|
||||||
- button "🖨️ Customer Address Printer"
|
|
||||||
- listitem:
|
|
||||||
- button "⚙️ Store Settings"
|
|
||||||
- heading "Customer Address Printer" [level=2]
|
|
||||||
- paragraph: Select an accepted order to view and print the shipping address label for the customer.
|
|
||||||
- heading "Print Configuration" [level=3]
|
|
||||||
- text: Select Accepted Order *
|
|
||||||
- combobox "Select Accepted Order *":
|
|
||||||
- option "-- Choose an accepted order --"
|
|
||||||
- option "22 - Alice Smith (Handmade Wool Blanket)" [selected]
|
|
||||||
- button "Print Address Label"
|
|
||||||
- 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
|
|
||||||
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();
|
|
||||||
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').first()).toBeVisible();
|
|
||||||
105 | await page.locator('button').filter({ hasText: 'Accept' }).first().click();
|
|
||||||
106 | await expect(page.getByText('Ready to Ship')).toBeVisible();
|
|
||||||
107 |
|
|
||||||
108 | // 10. Customer Address Printer
|
|
||||||
109 | await page.locator('button, a').filter({ hasText: 'Customer Address Printer' }).click();
|
|
||||||
110 | await expect(page.getByRole('heading', { name: 'Customer Address Printer' })).toBeVisible();
|
|
||||||
111 | await page.locator('select#print-order').selectOption({ index: 1 });
|
|
||||||
> 112 | await expect(page.getByText('Shipping Label Preview')).toBeVisible();
|
|
||||||
| ^ Error: expect(locator).toBeVisible() failed
|
|
||||||
113 | await expect(page.getByRole('button', { name: 'Print Address Label' })).toBeVisible();
|
|
||||||
114 | });
|
|
||||||
115 |
|
|
||||||
116 | test('enforces security constraints and validation rules (negative test cases)', async ({ page }) => {
|
|
||||||
117 | // 1. Visit Home and verify dashboard components are not in DOM (route guarding)
|
|
||||||
118 | await page.goto('/');
|
|
||||||
119 | await expect(page.locator('.dashboard-container')).toBeHidden();
|
|
||||||
120 | await expect(page.locator('.sidebar-menu')).toBeHidden();
|
|
||||||
121 |
|
|
||||||
122 | // 2. Go to Registration
|
|
||||||
123 | await page.locator('button, a').filter({ hasText: 'Get Started Today' }).first().click();
|
|
||||||
124 | const randSecurityUser = `security_test_${Date.now()}_${Math.floor(Math.random() * 1000000)}@example.com`;
|
|
||||||
125 | const randSecurityPhone = `9${Math.floor(100000000 + Math.random() * 900000000)}`;
|
|
||||||
126 | await page.locator('input#reg-email').fill(randSecurityUser);
|
|
||||||
127 | await page.locator('input#reg-phone').fill(randSecurityPhone);
|
|
||||||
128 | await page.locator('input#reg-pass').fill('Password123!');
|
|
||||||
129 | await page.locator('input#reg-confirm-pass').fill('Password123!');
|
|
||||||
130 | await page.locator('input#reg-policy').check();
|
|
||||||
131 | await page.locator('button').filter({ hasText: 'Register Business' }).click();
|
|
||||||
132 |
|
|
||||||
133 | // 3. Step 1: Negative OTP validations
|
|
||||||
134 | await expect(page.getByText('Step 1 of 3: Contact Verification')).toBeVisible();
|
|
||||||
135 |
|
|
||||||
136 | // Proceed button must be disabled initially
|
|
||||||
137 | await expect(page.locator('button').filter({ hasText: 'Next Step: Identity Verification' })).toBeDisabled();
|
|
||||||
138 |
|
|
||||||
139 | // Submit invalid WhatsApp OTP
|
|
||||||
140 | await page.locator('button').filter({ hasText: 'Send WhatsApp OTP' }).click();
|
|
||||||
141 | await page.locator('input[placeholder="Enter 123456"]').first().fill('000000');
|
|
||||||
142 |
|
|
||||||
143 | // Capture dialog
|
|
||||||
144 | let alertMessage = '';
|
|
||||||
145 | page.once('dialog', async dialog => {
|
|
||||||
146 | alertMessage = dialog.message();
|
|
||||||
147 | await dialog.accept();
|
|
||||||
148 | });
|
|
||||||
149 |
|
|
||||||
150 | await page.locator('button').filter({ hasText: 'Verify Code' }).first().click();
|
|
||||||
151 |
|
|
||||||
152 | // Give brief time/event loop ticks to ensure dialog handler fires
|
|
||||||
153 | await page.waitForTimeout(500);
|
|
||||||
154 | expect(alertMessage).toBe('Incorrect code. Enter 123456');
|
|
||||||
155 | await expect(page.getByText('✓ Mobile & WhatsApp Verified')).toBeHidden();
|
|
||||||
156 |
|
|
||||||
157 | // Correct the code to enable proceed
|
|
||||||
158 | await page.locator('input[placeholder="Enter 123456"]').first().clear();
|
|
||||||
159 | await page.locator('input[placeholder="Enter 123456"]').first().fill('123456');
|
|
||||||
160 | await page.locator('button').filter({ hasText: 'Verify Code' }).first().click();
|
|
||||||
161 | await expect(page.getByText('✓ Mobile & WhatsApp Verified')).toBeVisible();
|
|
||||||
162 |
|
|
||||||
163 | // Submit invalid Email OTP
|
|
||||||
164 | await page.locator('button').filter({ hasText: 'Send Email OTP' }).click();
|
|
||||||
165 | await page.locator('input[placeholder="Enter 123456"]').last().fill('999999');
|
|
||||||
166 |
|
|
||||||
167 | page.once('dialog', async dialog => {
|
|
||||||
168 | alertMessage = dialog.message();
|
|
||||||
169 | await dialog.accept();
|
|
||||||
170 | });
|
|
||||||
171 |
|
|
||||||
172 | await page.locator('button').filter({ hasText: 'Verify Code' }).last().click();
|
|
||||||
173 | await page.waitForTimeout(500);
|
|
||||||
174 | expect(alertMessage).toBe('Incorrect code. Enter 123456');
|
|
||||||
175 | await expect(page.getByText('✓ Email Verified')).toBeHidden();
|
|
||||||
176 | await expect(page.locator('button').filter({ hasText: 'Next Step: Identity Verification' })).toBeDisabled();
|
|
||||||
177 | });
|
|
||||||
178 | });
|
|
||||||
179 |
|
|
||||||
```
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 61 KiB |
Binary file not shown.
File diff suppressed because one or more lines are too long
0
prompt
Normal file
0
prompt
Normal file
|
|
@ -1,6 +1,4 @@
|
||||||
{
|
{
|
||||||
"status": "failed",
|
"status": "passed",
|
||||||
"failedTests": [
|
"failedTests": []
|
||||||
"fe534f0825407f213faa-eae28aa470cee3dd351a"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,250 +0,0 @@
|
||||||
# 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('Shipping Label Preview')
|
|
||||||
Expected: visible
|
|
||||||
Timeout: 5000ms
|
|
||||||
Error: element(s) not found
|
|
||||||
|
|
||||||
Call log:
|
|
||||||
- Expect "toBeVisible" with timeout 5000ms
|
|
||||||
- waiting for getByText('Shipping Label Preview')
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
- banner:
|
|
||||||
- text: A Global Artisans Hub
|
|
||||||
- navigation:
|
|
||||||
- button "Platform"
|
|
||||||
- button "Pricing"
|
|
||||||
- button "Success Stories"
|
|
||||||
- button "Support"
|
|
||||||
- button "Logout"
|
|
||||||
- complementary:
|
|
||||||
- text: SELLER PANEL
|
|
||||||
- heading "Teak Wood Craft Store" [level=4]
|
|
||||||
- list:
|
|
||||||
- listitem:
|
|
||||||
- button "📊 Overview & Analytics"
|
|
||||||
- listitem:
|
|
||||||
- button "📦 Manage Products"
|
|
||||||
- listitem:
|
|
||||||
- button "🚚 Orders & Transit"
|
|
||||||
- listitem:
|
|
||||||
- button "🔄 Returns Management"
|
|
||||||
- listitem:
|
|
||||||
- button "💼 Wallet & Payouts"
|
|
||||||
- listitem:
|
|
||||||
- button "🖨️ Customer Address Printer"
|
|
||||||
- listitem:
|
|
||||||
- button "⚙️ Store Settings"
|
|
||||||
- heading "Customer Address Printer" [level=2]
|
|
||||||
- paragraph: Select an accepted order to view and print the shipping address label for the customer.
|
|
||||||
- heading "Print Configuration" [level=3]
|
|
||||||
- text: Select Accepted Order *
|
|
||||||
- combobox "Select Accepted Order *":
|
|
||||||
- option "-- Choose an accepted order --"
|
|
||||||
- option "22 - Alice Smith (Handmade Wool Blanket)" [selected]
|
|
||||||
- button "Print Address Label"
|
|
||||||
- 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
|
|
||||||
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();
|
|
||||||
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').first()).toBeVisible();
|
|
||||||
105 | await page.locator('button').filter({ hasText: 'Accept' }).first().click();
|
|
||||||
106 | await expect(page.getByText('Ready to Ship')).toBeVisible();
|
|
||||||
107 |
|
|
||||||
108 | // 10. Customer Address Printer
|
|
||||||
109 | await page.locator('button, a').filter({ hasText: 'Customer Address Printer' }).click();
|
|
||||||
110 | await expect(page.getByRole('heading', { name: 'Customer Address Printer' })).toBeVisible();
|
|
||||||
111 | await page.locator('select#print-order').selectOption({ index: 1 });
|
|
||||||
> 112 | await expect(page.getByText('Shipping Label Preview')).toBeVisible();
|
|
||||||
| ^ Error: expect(locator).toBeVisible() failed
|
|
||||||
113 | await expect(page.getByRole('button', { name: 'Print Address Label' })).toBeVisible();
|
|
||||||
114 | });
|
|
||||||
115 |
|
|
||||||
116 | test('enforces security constraints and validation rules (negative test cases)', async ({ page }) => {
|
|
||||||
117 | // 1. Visit Home and verify dashboard components are not in DOM (route guarding)
|
|
||||||
118 | await page.goto('/');
|
|
||||||
119 | await expect(page.locator('.dashboard-container')).toBeHidden();
|
|
||||||
120 | await expect(page.locator('.sidebar-menu')).toBeHidden();
|
|
||||||
121 |
|
|
||||||
122 | // 2. Go to Registration
|
|
||||||
123 | await page.locator('button, a').filter({ hasText: 'Get Started Today' }).first().click();
|
|
||||||
124 | const randSecurityUser = `security_test_${Date.now()}_${Math.floor(Math.random() * 1000000)}@example.com`;
|
|
||||||
125 | const randSecurityPhone = `9${Math.floor(100000000 + Math.random() * 900000000)}`;
|
|
||||||
126 | await page.locator('input#reg-email').fill(randSecurityUser);
|
|
||||||
127 | await page.locator('input#reg-phone').fill(randSecurityPhone);
|
|
||||||
128 | await page.locator('input#reg-pass').fill('Password123!');
|
|
||||||
129 | await page.locator('input#reg-confirm-pass').fill('Password123!');
|
|
||||||
130 | await page.locator('input#reg-policy').check();
|
|
||||||
131 | await page.locator('button').filter({ hasText: 'Register Business' }).click();
|
|
||||||
132 |
|
|
||||||
133 | // 3. Step 1: Negative OTP validations
|
|
||||||
134 | await expect(page.getByText('Step 1 of 3: Contact Verification')).toBeVisible();
|
|
||||||
135 |
|
|
||||||
136 | // Proceed button must be disabled initially
|
|
||||||
137 | await expect(page.locator('button').filter({ hasText: 'Next Step: Identity Verification' })).toBeDisabled();
|
|
||||||
138 |
|
|
||||||
139 | // Submit invalid WhatsApp OTP
|
|
||||||
140 | await page.locator('button').filter({ hasText: 'Send WhatsApp OTP' }).click();
|
|
||||||
141 | await page.locator('input[placeholder="Enter 123456"]').first().fill('000000');
|
|
||||||
142 |
|
|
||||||
143 | // Capture dialog
|
|
||||||
144 | let alertMessage = '';
|
|
||||||
145 | page.once('dialog', async dialog => {
|
|
||||||
146 | alertMessage = dialog.message();
|
|
||||||
147 | await dialog.accept();
|
|
||||||
148 | });
|
|
||||||
149 |
|
|
||||||
150 | await page.locator('button').filter({ hasText: 'Verify Code' }).first().click();
|
|
||||||
151 |
|
|
||||||
152 | // Give brief time/event loop ticks to ensure dialog handler fires
|
|
||||||
153 | await page.waitForTimeout(500);
|
|
||||||
154 | expect(alertMessage).toBe('Incorrect code. Enter 123456');
|
|
||||||
155 | await expect(page.getByText('✓ Mobile & WhatsApp Verified')).toBeHidden();
|
|
||||||
156 |
|
|
||||||
157 | // Correct the code to enable proceed
|
|
||||||
158 | await page.locator('input[placeholder="Enter 123456"]').first().clear();
|
|
||||||
159 | await page.locator('input[placeholder="Enter 123456"]').first().fill('123456');
|
|
||||||
160 | await page.locator('button').filter({ hasText: 'Verify Code' }).first().click();
|
|
||||||
161 | await expect(page.getByText('✓ Mobile & WhatsApp Verified')).toBeVisible();
|
|
||||||
162 |
|
|
||||||
163 | // Submit invalid Email OTP
|
|
||||||
164 | await page.locator('button').filter({ hasText: 'Send Email OTP' }).click();
|
|
||||||
165 | await page.locator('input[placeholder="Enter 123456"]').last().fill('999999');
|
|
||||||
166 |
|
|
||||||
167 | page.once('dialog', async dialog => {
|
|
||||||
168 | alertMessage = dialog.message();
|
|
||||||
169 | await dialog.accept();
|
|
||||||
170 | });
|
|
||||||
171 |
|
|
||||||
172 | await page.locator('button').filter({ hasText: 'Verify Code' }).last().click();
|
|
||||||
173 | await page.waitForTimeout(500);
|
|
||||||
174 | expect(alertMessage).toBe('Incorrect code. Enter 123456');
|
|
||||||
175 | await expect(page.getByText('✓ Email Verified')).toBeHidden();
|
|
||||||
176 | await expect(page.locator('button').filter({ hasText: 'Next Step: Identity Verification' })).toBeDisabled();
|
|
||||||
177 | });
|
|
||||||
178 | });
|
|
||||||
179 |
|
|
||||||
```
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 61 KiB |
Binary file not shown.
Loading…
Reference in a new issue