- Add Lead Requests page with filters and cancel functionality - Add Accepted Leads page with contact details and WhatsApp integration - Add Buy Tracecoins checkout flow with Beeceptor payment - Add Invoice Detail page with GST breakdown - Add NotificationBell component with 30s polling - Add manual E2E test script - Update Playwright tests for company verification flow
297 lines
11 KiB
TypeScript
297 lines
11 KiB
TypeScript
import { test, expect, chromium } from "@playwright/test";
|
||
import { randomUUID } from "crypto";
|
||
|
||
// Generate random test data
|
||
const testEmail = `testcompany${randomUUID().slice(0, 8)}@test.com`;
|
||
const testPassword = "TestPassword123!";
|
||
const testCompanyName = `Test Company ${randomUUID().slice(0, 6)}`;
|
||
const firstName = "John";
|
||
const lastName = "Doe";
|
||
|
||
console.log("🧪 Starting E2E Test Flow");
|
||
console.log("📧 Test Email:", testEmail);
|
||
console.log("🏢 Company Name:", testCompanyName);
|
||
|
||
test.setTimeout(300000); // 5 minutes to allow manual CAPTCHA entry
|
||
|
||
test("Company signup -> verification flow", async () => {
|
||
// Launch browser with UI visible
|
||
const browser = await chromium.launch({
|
||
headless: false,
|
||
slowMo: 200,
|
||
});
|
||
|
||
const context = await browser.newContext({
|
||
viewport: { width: 1400, height: 900 },
|
||
recordVideo: {
|
||
dir: "./test-videos/",
|
||
size: { width: 1400, height: 900 },
|
||
},
|
||
});
|
||
|
||
const page = await context.newPage();
|
||
|
||
try {
|
||
// Step 1: Navigate to public website signup
|
||
console.log("🌐 Step 1: Opening public website signup...");
|
||
await page.goto("http://localhost:3001/signup?intent=company");
|
||
await page.waitForLoadState("networkidle");
|
||
|
||
await page.screenshot({ path: "./test-results/01-signup-page.png", fullPage: true });
|
||
console.log("📸 Screenshot: Signup page");
|
||
|
||
// Step 2: Fill signup form with all required fields
|
||
console.log("✍️ Step 2: Filling signup form...");
|
||
|
||
// Fill First Name
|
||
await page.fill("#first-name", firstName);
|
||
console.log(" ✓ First Name filled");
|
||
|
||
// Fill Last Name
|
||
await page.fill("#last-name", lastName);
|
||
console.log(" ✓ Last Name filled");
|
||
|
||
// Fill Email
|
||
await page.fill("#email", testEmail);
|
||
console.log(" ✓ Email filled:", testEmail);
|
||
|
||
// Fill Password
|
||
await page.fill("#password", testPassword);
|
||
console.log(" ✓ Password filled");
|
||
|
||
// Fill Confirm Password
|
||
await page.fill("#confirm-password", testPassword);
|
||
console.log(" ✓ Confirm Password filled");
|
||
|
||
// Check Terms checkbox
|
||
await page.check('input[type="checkbox"]');
|
||
console.log(" ✓ Terms & Conditions checked");
|
||
|
||
await page.screenshot({ path: "./test-results/02-signup-filled.png", fullPage: true });
|
||
console.log("📸 Screenshot: Signup form filled");
|
||
|
||
// Step 3: Handle CAPTCHA (manual entry required)
|
||
console.log("\n🔐 Step 3: CAPTCHA Required");
|
||
console.log(
|
||
" Please look at the browser window and enter the CAPTCHA code shown on the canvas."
|
||
);
|
||
console.log(" The test will wait for 60 seconds...\n");
|
||
|
||
// Wait for CAPTCHA to be entered and validated (user must type in the browser)
|
||
// The button will enable when all fields are valid
|
||
await page.waitForFunction(
|
||
() => {
|
||
const btn = document.querySelector(".auth-submit-btn");
|
||
return btn && !(btn as HTMLButtonElement).disabled;
|
||
},
|
||
{ timeout: 60000 }
|
||
);
|
||
|
||
console.log(" ✓ CAPTCHA entered (button is now enabled)");
|
||
|
||
// Click Sign Up button
|
||
await page.click(".auth-submit-btn");
|
||
console.log(" ✓ Sign Up button clicked");
|
||
|
||
await page.waitForTimeout(3000);
|
||
await page.screenshot({ path: "./test-results/03-after-signup.png", fullPage: true });
|
||
console.log("📸 Screenshot: After signup");
|
||
|
||
// Step 4: Handle OTP Verification
|
||
console.log("📧 Step 4: OTP Verification");
|
||
console.log(" Please check your email for the OTP and enter it in the browser.");
|
||
console.log(" The test will wait for 60 seconds...\n");
|
||
|
||
// Wait for OTP to be entered and verified
|
||
await page.waitForFunction(
|
||
() => {
|
||
// Wait for success message or redirect
|
||
return (
|
||
document.body.innerText.includes("verified") ||
|
||
document.body.innerText.includes("Redirecting") ||
|
||
window.location.pathname.includes("/login")
|
||
);
|
||
},
|
||
{ timeout: 60000 }
|
||
);
|
||
|
||
console.log(" ✓ Email verified!");
|
||
await page.waitForTimeout(2000);
|
||
|
||
await page.screenshot({ path: "./test-results/04-email-verified.png", fullPage: true });
|
||
console.log("📸 Screenshot: Email verified");
|
||
|
||
// Step 5: Login with new credentials
|
||
console.log("🔑 Step 5: Logging in...");
|
||
|
||
// Should be redirected to login, or navigate there
|
||
if (!page.url().includes("/login")) {
|
||
await page.goto("http://localhost:3001/login");
|
||
await page.waitForLoadState("networkidle");
|
||
}
|
||
|
||
await page.fill('input[type="email"], input[name="email"]', testEmail);
|
||
await page.fill('input[type="password"], input[name="password"]', testPassword);
|
||
await page.click('button[type="submit"], .auth-submit-btn');
|
||
|
||
await page.waitForTimeout(3000);
|
||
console.log(" ✓ Logged in successfully");
|
||
|
||
await page.screenshot({ path: "./test-results/05-logged-in.png", fullPage: true });
|
||
console.log("📸 Screenshot: After login");
|
||
|
||
// Step 6: Navigate to Company Profile
|
||
console.log("🏢 Step 6: Filling company profile...");
|
||
|
||
// Look for profile/settings or company setup
|
||
const profileLink = await page.locator("text=Profile, text=Company, text=Settings").first();
|
||
if (await profileLink.isVisible().catch(() => false)) {
|
||
await profileLink.click();
|
||
await page.waitForTimeout(2000);
|
||
}
|
||
|
||
// Fill company details if form is present
|
||
const companyNameInput = await page
|
||
.locator('input[name="companyName"], input[name="name"], input[placeholder*="company"]')
|
||
.first();
|
||
if (await companyNameInput.isVisible().catch(() => false)) {
|
||
await companyNameInput.fill(testCompanyName);
|
||
|
||
// Try to fill other fields if they exist
|
||
const websiteInput = await page.locator('input[name="website"]').first();
|
||
if (await websiteInput.isVisible().catch(() => false)) {
|
||
await websiteInput.fill("https://testcompany.com");
|
||
}
|
||
|
||
const phoneInput = await page
|
||
.locator('input[name="phone"], input[name="contactPhone"]')
|
||
.first();
|
||
if (await phoneInput.isVisible().catch(() => false)) {
|
||
await phoneInput.fill("+91 9876543210");
|
||
}
|
||
|
||
const addressInput = await page
|
||
.locator('textarea[name="address"], input[name="address"]')
|
||
.first();
|
||
if (await addressInput.isVisible().catch(() => false)) {
|
||
await addressInput.fill("123 Tech Park, Bangalore, Karnataka 560001");
|
||
}
|
||
|
||
// Submit profile
|
||
const saveBtn = await page
|
||
.locator('button[type="submit"], button:has-text("Save"), button:has-text("Submit")')
|
||
.first();
|
||
if (await saveBtn.isVisible().catch(() => false)) {
|
||
await saveBtn.click();
|
||
await page.waitForTimeout(3000);
|
||
console.log(" ✓ Company profile submitted");
|
||
}
|
||
} else {
|
||
console.log(" ℹ️ Company profile form not found (may already be set up or different flow)");
|
||
}
|
||
|
||
await page.screenshot({ path: "./test-results/06-company-profile.png", fullPage: true });
|
||
console.log("📸 Screenshot: Company profile");
|
||
|
||
// Step 7: Open Admin Panel
|
||
console.log("🔐 Step 7: Opening admin panel...");
|
||
const adminPage = await context.newPage();
|
||
await adminPage.goto("http://localhost:3000/login");
|
||
await adminPage.waitForLoadState("networkidle");
|
||
|
||
await adminPage.screenshot({ path: "./test-results/07-admin-login.png", fullPage: true });
|
||
console.log("📸 Screenshot: Admin login page");
|
||
|
||
// Admin login (default credentials)
|
||
await adminPage.fill('input[type="email"], input[name="email"]', "admin@nxtgauge.com");
|
||
await adminPage.fill('input[type="password"], input[name="password"]', "admin123");
|
||
await adminPage.click(
|
||
'button[type="submit"], button:has-text("Login"), button:has-text("Sign In")'
|
||
);
|
||
|
||
await adminPage.waitForTimeout(3000);
|
||
console.log(" ✓ Admin logged in");
|
||
|
||
await adminPage.screenshot({ path: "./test-results/08-admin-dashboard.png", fullPage: true });
|
||
console.log("📸 Screenshot: Admin dashboard");
|
||
|
||
// Step 8: Navigate to Verification Management
|
||
console.log("🔍 Step 8: Navigating to Verification Management...");
|
||
|
||
// Try different selectors for Verifications link
|
||
const verificationsSelectors = [
|
||
"text=Verifications",
|
||
'a:has-text("Verifications")',
|
||
'[href*="verification"]',
|
||
"text=Verify",
|
||
"text=Pending",
|
||
];
|
||
|
||
let verificationClicked = false;
|
||
for (const selector of verificationsSelectors) {
|
||
const link = await adminPage.locator(selector).first();
|
||
if (await link.isVisible().catch(() => false)) {
|
||
await link.click();
|
||
verificationClicked = true;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (!verificationClicked) {
|
||
console.log(" ⚠️ Could not find Verifications link - may need to check sidebar navigation");
|
||
}
|
||
|
||
await adminPage.waitForTimeout(3000);
|
||
await adminPage.screenshot({ path: "./test-results/09-verification-list.png", fullPage: true });
|
||
console.log("📸 Screenshot: Verification list page");
|
||
|
||
// Step 9: Check if our company appears in verification queue
|
||
console.log("🔎 Step 9: Checking for company verification request...");
|
||
|
||
// Search for the company name or email
|
||
const searchInput = await adminPage
|
||
.locator('input[placeholder*="search" i], input[name="search"]')
|
||
.first();
|
||
if (await searchInput.isVisible().catch(() => false)) {
|
||
await searchInput.fill(testEmail);
|
||
await adminPage.waitForTimeout(2000);
|
||
|
||
await adminPage.screenshot({ path: "./test-results/10-search-results.png", fullPage: true });
|
||
console.log("📸 Screenshot: Search results");
|
||
}
|
||
|
||
// Check if company is found
|
||
const pageContent = await adminPage.locator("body").innerText();
|
||
const companyFound = pageContent.includes(testEmail) || pageContent.includes(testCompanyName);
|
||
|
||
if (companyFound) {
|
||
console.log("✅ SUCCESS: Company verification request found in admin panel!");
|
||
console.log(" Email:", testEmail);
|
||
console.log(" Company:", testCompanyName);
|
||
} else {
|
||
console.log("⚠️ Company not immediately found in verification queue");
|
||
console.log(" This might be because:");
|
||
console.log(" - The profile is still being processed");
|
||
console.log(" - The verification queue uses different filters");
|
||
console.log(" - The admin credentials are incorrect");
|
||
console.log(" - The company verification happens in a different section");
|
||
}
|
||
|
||
// Keep browser open for review
|
||
console.log("\n⏳ Keeping browser open for 15 seconds for review...");
|
||
await page.waitForTimeout(15000);
|
||
|
||
console.log("\n✅ E2E Test Flow Completed!");
|
||
console.log("📧 Test Account:", testEmail);
|
||
console.log("🔑 Password:", testPassword);
|
||
} catch (error) {
|
||
console.error("❌ Test failed:", error);
|
||
await page.screenshot({ path: "./test-results/error-screenshot.png", fullPage: true });
|
||
throw error;
|
||
} finally {
|
||
await context.close();
|
||
await browser.close();
|
||
console.log("\n📹 Video saved to: ./test-videos/");
|
||
console.log("📸 Screenshots saved to: ./test-results/");
|
||
}
|
||
});
|