fix: Chrome rendering and scrolling issues
- Changed overflow-x: clip to overflow-x: hidden for better Chrome support - Changed auth-layout align-items from center to start to prevent clipping - Added overflow-y: auto and overflow-x: hidden to body for consistent scrolling Fixes issues where header and signup form were not visible in Chrome and users were unable to scroll.
This commit is contained in:
parent
f27713a136
commit
6f88aa9627
7 changed files with 1157 additions and 114 deletions
21
frontend.log
Normal file
21
frontend.log
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
|
||||||
|
> dev
|
||||||
|
> vinxi dev
|
||||||
|
|
||||||
|
vinxi v0.5.11
|
||||||
|
vinxi found vinxi app config in vite.config.ts
|
||||||
|
vinxi starting dev server
|
||||||
|
[get-port] Unable to find an available port (tried 3000 on host "localhost"). Using alternative port 3001.
|
||||||
|
|
||||||
|
➜ Local: http://localhost:3001/
|
||||||
|
➜ Network: use --host to expose
|
||||||
|
|
||||||
|
2:43:36 AM [vite] (client) page reload live-demo.cjs
|
||||||
|
2:47:39 AM [vite] (ssr) hmr update /src/app.css
|
||||||
|
2:47:39 AM [vite] (client) hmr update /src/app.css
|
||||||
|
2:47:39 AM [vite] (ssr) hmr update /src/app.css
|
||||||
|
2:47:39 AM [vite] (client) hmr update /src/app.css
|
||||||
|
2:48:23 AM [vite] (ssr) hmr update /src/app.css
|
||||||
|
2:48:23 AM [vite] (client) hmr update /src/app.css
|
||||||
|
2:48:38 AM [vite] (ssr) hmr update /src/app.css
|
||||||
|
2:48:38 AM [vite] (client) hmr update /src/app.css
|
||||||
176
live-demo-manual.cjs
Normal file
176
live-demo-manual.cjs
Normal file
|
|
@ -0,0 +1,176 @@
|
||||||
|
const { chromium } = require("playwright");
|
||||||
|
const { randomUUID } = require("crypto");
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
console.log("🎭 Starting Live UI Testing Demo\n");
|
||||||
|
|
||||||
|
const testEmail = `testcompany${randomUUID().slice(0, 8)}@test.com`;
|
||||||
|
const testPassword = "TestPass123!";
|
||||||
|
const testCompanyName = `Test Company ${randomUUID().slice(0, 6)}`;
|
||||||
|
const firstName = "John";
|
||||||
|
const lastName = "Doe";
|
||||||
|
|
||||||
|
console.log("📧 Test Email:", testEmail);
|
||||||
|
console.log("👤 Name:", firstName, lastName);
|
||||||
|
console.log("🏢 Company Name:", testCompanyName);
|
||||||
|
console.log("\n🚀 Launching Chromium browser...\n");
|
||||||
|
|
||||||
|
const browser = await chromium.launch({
|
||||||
|
headless: false,
|
||||||
|
slowMo: 600,
|
||||||
|
args: ["--window-size=1400,900"],
|
||||||
|
});
|
||||||
|
|
||||||
|
const context = await browser.newContext({
|
||||||
|
viewport: { width: 1400, height: 900 },
|
||||||
|
});
|
||||||
|
|
||||||
|
const page = await context.newPage();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Step 1: Navigate to signup
|
||||||
|
console.log("📍 Step 1: Opening signup page...");
|
||||||
|
await page.goto("http://localhost:3001/signup?intent=company");
|
||||||
|
await page.waitForTimeout(3000);
|
||||||
|
|
||||||
|
// Step 2: Fill ALL required fields using correct selectors
|
||||||
|
console.log("✍️ Step 2: Filling ALL required fields...\n");
|
||||||
|
|
||||||
|
// First Name (id="first-name")
|
||||||
|
console.log(" → First Name...");
|
||||||
|
await page.fill("#first-name", firstName);
|
||||||
|
await page.waitForTimeout(300);
|
||||||
|
|
||||||
|
// Last Name (id="last-name")
|
||||||
|
console.log(" → Last Name...");
|
||||||
|
await page.fill("#last-name", lastName);
|
||||||
|
await page.waitForTimeout(300);
|
||||||
|
|
||||||
|
// Email (id="email")
|
||||||
|
console.log(" → Email...");
|
||||||
|
await page.fill("#email", testEmail);
|
||||||
|
await page.waitForTimeout(300);
|
||||||
|
|
||||||
|
// Password (id="password")
|
||||||
|
console.log(" → Password...");
|
||||||
|
await page.fill("#password", testPassword);
|
||||||
|
await page.waitForTimeout(300);
|
||||||
|
|
||||||
|
// Confirm Password (id="confirm-password")
|
||||||
|
console.log(" → Confirm Password...");
|
||||||
|
await page.fill("#confirm-password", testPassword);
|
||||||
|
await page.waitForTimeout(300);
|
||||||
|
|
||||||
|
// CAPTCHA (id="captcha") - Need to read from canvas
|
||||||
|
console.log(" → CAPTCHA...");
|
||||||
|
// For demo purposes, we'll need to manually handle this or skip
|
||||||
|
// The captcha is drawn on a canvas, we can't easily read it
|
||||||
|
// Let's fill a placeholder and see what happens
|
||||||
|
await page.fill("#captcha", "TEST12");
|
||||||
|
console.log(" ⚠️ Note: CAPTCHA filled with placeholder");
|
||||||
|
await page.waitForTimeout(300);
|
||||||
|
|
||||||
|
// Terms Checkbox
|
||||||
|
console.log(" → Terms & Conditions...");
|
||||||
|
await page.check(".auth-checkbox");
|
||||||
|
console.log(" ✅ Terms checked");
|
||||||
|
await page.waitForTimeout(300);
|
||||||
|
|
||||||
|
console.log("\n✅ All fields filled!");
|
||||||
|
await page.waitForTimeout(1500);
|
||||||
|
|
||||||
|
// Take screenshot before submit
|
||||||
|
await page.screenshot({ path: "./test-results/02-signup-filled.png", fullPage: true });
|
||||||
|
|
||||||
|
// Step 3: Check if button is enabled
|
||||||
|
console.log("\n📤 Step 3: Checking Sign Up button...");
|
||||||
|
const submitBtn = await page.locator(".auth-submit-btn");
|
||||||
|
const isDisabled = await submitBtn.isDisabled();
|
||||||
|
|
||||||
|
if (isDisabled) {
|
||||||
|
console.log("⚠️ Button is still disabled - CAPTCHA may be invalid");
|
||||||
|
console.log(" 📝 In real usage, user would need to:");
|
||||||
|
console.log(" 1. Read the CAPTCHA from the canvas image");
|
||||||
|
console.log(" 2. Enter the correct CAPTCHA code");
|
||||||
|
console.log(" 3. Then click Sign Up");
|
||||||
|
|
||||||
|
// For demo, let's try refreshing the captcha and entering a new one
|
||||||
|
console.log(" 🔄 Refreshing CAPTCHA...");
|
||||||
|
await page.click(".auth-captcha-refresh");
|
||||||
|
await page.waitForTimeout(1000);
|
||||||
|
|
||||||
|
// Note: We still can't read the canvas captcha programmatically
|
||||||
|
// This is where manual intervention is needed in real testing
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("\n⏸️ PAUSED: Manual CAPTCHA entry required");
|
||||||
|
console.log(" Please manually:");
|
||||||
|
console.log(" 1. Look at the CAPTCHA image in the browser");
|
||||||
|
console.log(" 2. Clear the CAPTCHA field");
|
||||||
|
console.log(" 3. Enter the correct CAPTCHA code");
|
||||||
|
console.log(" 4. Click the Sign Up button");
|
||||||
|
console.log(" 5. Complete the email verification");
|
||||||
|
console.log("\n Browser will stay open for 60 seconds...");
|
||||||
|
console.log(" (Take your time to complete the flow manually)");
|
||||||
|
|
||||||
|
// Keep browser open for manual interaction
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, 60000));
|
||||||
|
|
||||||
|
// After manual completion, check current URL
|
||||||
|
const currentUrl = page.url();
|
||||||
|
console.log("\n📍 Current URL after manual flow:", currentUrl);
|
||||||
|
|
||||||
|
// If we reached the dashboard or verification page
|
||||||
|
if (currentUrl.includes("dashboard") || currentUrl.includes("verify")) {
|
||||||
|
console.log("✅ Signup flow completed!");
|
||||||
|
await page.screenshot({ path: "./test-results/03-after-signup.png", fullPage: true });
|
||||||
|
|
||||||
|
// Now check admin panel
|
||||||
|
console.log("\n🔐 Opening Admin Panel to check verification...");
|
||||||
|
const adminPage = await context.newPage();
|
||||||
|
await adminPage.goto("http://localhost:3000/login");
|
||||||
|
await adminPage.waitForTimeout(2000);
|
||||||
|
|
||||||
|
// Admin login
|
||||||
|
await adminPage.fill('input[type="email"]', "admin@nxtgauge.com");
|
||||||
|
await adminPage.fill('input[type="password"]', "admin123");
|
||||||
|
await adminPage.click('button[type="submit"]');
|
||||||
|
await adminPage.waitForTimeout(3000);
|
||||||
|
|
||||||
|
// Go to verification
|
||||||
|
await adminPage.goto("http://localhost:3000/admin/verification");
|
||||||
|
await adminPage.waitForTimeout(3000);
|
||||||
|
|
||||||
|
// Search for company
|
||||||
|
const searchInput = await adminPage.locator('input[type="search"]').first();
|
||||||
|
if (searchInput) {
|
||||||
|
await searchInput.fill(testEmail);
|
||||||
|
await adminPage.waitForTimeout(2000);
|
||||||
|
}
|
||||||
|
|
||||||
|
await adminPage.screenshot({
|
||||||
|
path: "./test-results/04-admin-verification.png",
|
||||||
|
fullPage: true,
|
||||||
|
});
|
||||||
|
console.log("📸 Admin screenshot saved");
|
||||||
|
|
||||||
|
const companyFound = await adminPage
|
||||||
|
.locator(`text=${testEmail}`)
|
||||||
|
.isVisible()
|
||||||
|
.catch(() => false);
|
||||||
|
if (companyFound) {
|
||||||
|
console.log("✅ SUCCESS! Company found in verification queue!");
|
||||||
|
} else {
|
||||||
|
console.log("⚠️ Company not found - may still be processing");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("\n❌ Error:", error.message);
|
||||||
|
await page.screenshot({ path: "./test-results/error.png", fullPage: true });
|
||||||
|
} finally {
|
||||||
|
await context.close();
|
||||||
|
await browser.close();
|
||||||
|
console.log("\n✅ Test completed");
|
||||||
|
console.log("📸 Screenshots in ./test-results/");
|
||||||
|
}
|
||||||
|
})();
|
||||||
357
live-demo.cjs
Normal file
357
live-demo.cjs
Normal file
|
|
@ -0,0 +1,357 @@
|
||||||
|
const { chromium } = require("playwright");
|
||||||
|
const { randomUUID } = require("crypto");
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
console.log("🎭 Starting Live UI Testing Demo\n");
|
||||||
|
|
||||||
|
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("📧 Test Email:", testEmail);
|
||||||
|
console.log("👤 Name:", firstName, lastName);
|
||||||
|
console.log("🏢 Company Name:", testCompanyName);
|
||||||
|
console.log("\n🚀 Launching Chromium browser with visible window...\n");
|
||||||
|
|
||||||
|
const browser = await chromium.launch({
|
||||||
|
headless: false,
|
||||||
|
slowMo: 800,
|
||||||
|
args: ["--window-size=1400,900"],
|
||||||
|
});
|
||||||
|
|
||||||
|
const context = await browser.newContext({
|
||||||
|
viewport: { width: 1400, height: 900 },
|
||||||
|
});
|
||||||
|
|
||||||
|
const page = await context.newPage();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Step 1: Navigate to signup
|
||||||
|
console.log("📍 Step 1: Opening signup page...");
|
||||||
|
await page.goto("http://localhost:3001/signup?intent=company");
|
||||||
|
await page.waitForTimeout(3000);
|
||||||
|
|
||||||
|
// Step 2: Fill ALL required fields
|
||||||
|
console.log("✍️ Step 2: Filling ALL required fields...\n");
|
||||||
|
|
||||||
|
// First Name
|
||||||
|
console.log(" → First Name...");
|
||||||
|
const firstNameInput = await page
|
||||||
|
.locator('input[name="firstName"], input[placeholder*="First"]')
|
||||||
|
.first();
|
||||||
|
await firstNameInput.fill(firstName);
|
||||||
|
await page.waitForTimeout(500);
|
||||||
|
|
||||||
|
// Last Name
|
||||||
|
console.log(" → Last Name...");
|
||||||
|
const lastNameInput = await page
|
||||||
|
.locator('input[name="lastName"], input[placeholder*="Last"]')
|
||||||
|
.first();
|
||||||
|
await lastNameInput.fill(lastName);
|
||||||
|
await page.waitForTimeout(500);
|
||||||
|
|
||||||
|
// Email
|
||||||
|
console.log(" → Email...");
|
||||||
|
const emailInput = await page
|
||||||
|
.locator('input[type="email"], input[name="email"]')
|
||||||
|
.first();
|
||||||
|
await emailInput.fill(testEmail);
|
||||||
|
await page.waitForTimeout(500);
|
||||||
|
|
||||||
|
// Password
|
||||||
|
console.log(" → Password...");
|
||||||
|
const passwordInput = await page.locator('input[name="password"]').first();
|
||||||
|
await passwordInput.fill(testPassword);
|
||||||
|
await page.waitForTimeout(500);
|
||||||
|
|
||||||
|
// Confirm Password
|
||||||
|
console.log(" → Confirm Password...");
|
||||||
|
const confirmInput = await page
|
||||||
|
.locator('input[name="confirmPassword"], input[name="confirm"]')
|
||||||
|
.first();
|
||||||
|
await confirmInput.fill(testPassword);
|
||||||
|
await page.waitForTimeout(500);
|
||||||
|
|
||||||
|
// CAPTCHA - Read the code from the canvas/image
|
||||||
|
console.log(" → Reading CAPTCHA code...");
|
||||||
|
const captchaText = await page
|
||||||
|
.locator(".captcha-code, [data-captcha], .captcha-display")
|
||||||
|
.textContent()
|
||||||
|
.catch(() => null);
|
||||||
|
if (captchaText) {
|
||||||
|
console.log(" → CAPTCHA found:", captchaText.trim());
|
||||||
|
const captchaInput = await page
|
||||||
|
.locator('input[name="captcha"], input[placeholder*="CAPTCHA"]')
|
||||||
|
.first();
|
||||||
|
await captchaInput.fill(captchaText.trim());
|
||||||
|
} else {
|
||||||
|
console.log(" → CAPTCHA not readable, will try to find input...");
|
||||||
|
// Try to get from a data attribute or regenerate
|
||||||
|
const captchaInput = await page.locator('input[name="captcha"]').first();
|
||||||
|
if (captchaInput) {
|
||||||
|
// Look for any visible captcha text
|
||||||
|
const captchaCode = await page.evaluate(() => {
|
||||||
|
const el = document.querySelector(
|
||||||
|
".captcha-code, .captcha-text, [data-captcha]",
|
||||||
|
);
|
||||||
|
return el ? el.textContent || el.getAttribute("data-captcha") : null;
|
||||||
|
});
|
||||||
|
if (captchaCode) {
|
||||||
|
await captchaInput.fill(captchaCode.trim());
|
||||||
|
console.log(" → CAPTCHA filled:", captchaCode.trim());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await page.waitForTimeout(500);
|
||||||
|
|
||||||
|
// Terms Checkbox
|
||||||
|
console.log(" → Checking Terms & Conditions...");
|
||||||
|
const termsCheckbox = await page
|
||||||
|
.locator(
|
||||||
|
'input[type="checkbox"][name*="terms"], input[type="checkbox"][name*="agree"]',
|
||||||
|
)
|
||||||
|
.first();
|
||||||
|
if (termsCheckbox) {
|
||||||
|
await termsCheckbox.check();
|
||||||
|
console.log(" ✅ Terms checkbox checked");
|
||||||
|
}
|
||||||
|
await page.waitForTimeout(500);
|
||||||
|
|
||||||
|
console.log("\n✅ All fields filled!");
|
||||||
|
await page.waitForTimeout(2000);
|
||||||
|
|
||||||
|
// Step 3: Submit signup
|
||||||
|
console.log("\n📤 Step 3: Clicking Sign Up button...");
|
||||||
|
const submitBtn = await page
|
||||||
|
.locator(
|
||||||
|
'button[type="submit"]:has-text("Sign"), button:has-text("Create"), button:has-text("Register")',
|
||||||
|
)
|
||||||
|
.first();
|
||||||
|
|
||||||
|
// Check if button is enabled
|
||||||
|
const isDisabled = await submitBtn.isDisabled().catch(() => false);
|
||||||
|
if (isDisabled) {
|
||||||
|
console.log("⚠️ Button is disabled - checking what field is missing...");
|
||||||
|
// Take screenshot to debug
|
||||||
|
await page.screenshot({
|
||||||
|
path: "./test-results/signup-debug.png",
|
||||||
|
fullPage: true,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
await submitBtn.click();
|
||||||
|
console.log("✅ Sign Up button clicked");
|
||||||
|
}
|
||||||
|
await page.waitForTimeout(5000);
|
||||||
|
|
||||||
|
// Step 4: Check current page
|
||||||
|
const currentUrl = page.url();
|
||||||
|
console.log("\n📍 Current URL:", currentUrl);
|
||||||
|
|
||||||
|
if (currentUrl.includes("verify") || currentUrl.includes("otp")) {
|
||||||
|
console.log("📧 Step 4: OTP verification page detected");
|
||||||
|
console.log(" → Entering OTP...");
|
||||||
|
|
||||||
|
// Fill OTP (6 digits)
|
||||||
|
const otpDigits = ["1", "2", "3", "4", "5", "6"];
|
||||||
|
for (let i = 0; i < 6; i++) {
|
||||||
|
const otpInput = await page
|
||||||
|
.locator(`input[name="otp${i}"], input[aria-label*="digit ${i + 1}"]`)
|
||||||
|
.first();
|
||||||
|
if (otpInput) {
|
||||||
|
await otpInput.fill(otpDigits[i]);
|
||||||
|
await page.waitForTimeout(200);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Submit OTP
|
||||||
|
const verifyBtn = await page
|
||||||
|
.locator('button:has-text("Verify"), button[type="submit"]')
|
||||||
|
.first();
|
||||||
|
await verifyBtn.click();
|
||||||
|
console.log("✅ OTP submitted");
|
||||||
|
await page.waitForTimeout(4000);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 5: Select Company role if on role selection page
|
||||||
|
console.log("\n🎯 Step 5: Checking for role selection...");
|
||||||
|
const roleOption = await page.locator("text=Company").first();
|
||||||
|
if (await roleOption.isVisible().catch(() => false)) {
|
||||||
|
await roleOption.click();
|
||||||
|
console.log("✅ Company role selected");
|
||||||
|
await page.waitForTimeout(3000);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 6: Fill Company Profile
|
||||||
|
console.log("\n📝 Step 6: Filling company profile...");
|
||||||
|
|
||||||
|
// Company name
|
||||||
|
const nameInputs = await page
|
||||||
|
.locator(
|
||||||
|
'input[name*="company"], input[name*="name"], input[placeholder*="Company"]',
|
||||||
|
)
|
||||||
|
.all();
|
||||||
|
for (const input of nameInputs.slice(0, 3)) {
|
||||||
|
try {
|
||||||
|
const placeholder = await input.getAttribute("placeholder");
|
||||||
|
const name = await input.getAttribute("name");
|
||||||
|
|
||||||
|
if (
|
||||||
|
placeholder?.toLowerCase().includes("company") ||
|
||||||
|
name?.toLowerCase().includes("company")
|
||||||
|
) {
|
||||||
|
await input.fill(testCompanyName);
|
||||||
|
console.log(" ✅ Company name:", testCompanyName);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch (e) {}
|
||||||
|
}
|
||||||
|
await page.waitForTimeout(1000);
|
||||||
|
|
||||||
|
// Fill other profile fields
|
||||||
|
const inputs = await page.locator("input, textarea, select").all();
|
||||||
|
for (const input of inputs) {
|
||||||
|
try {
|
||||||
|
const type = await input.getAttribute("type");
|
||||||
|
const name = await input.getAttribute("name");
|
||||||
|
const tagName = await input.evaluate((el) => el.tagName.toLowerCase());
|
||||||
|
|
||||||
|
if (tagName === "select") {
|
||||||
|
// Select dropdown
|
||||||
|
const options = await input.locator("option").all();
|
||||||
|
if (options.length > 1) {
|
||||||
|
await input.selectOption({ index: 1 });
|
||||||
|
}
|
||||||
|
} else if (type === "email" || name?.includes("email")) {
|
||||||
|
await input.fill(testEmail);
|
||||||
|
} else if (name?.includes("phone") || name?.includes("contact")) {
|
||||||
|
await input.fill("+91 9876543210");
|
||||||
|
} else if (name?.includes("city")) {
|
||||||
|
await input.fill("Bangalore");
|
||||||
|
} else if (name?.includes("state")) {
|
||||||
|
await input.fill("Karnataka");
|
||||||
|
} else if (name?.includes("country")) {
|
||||||
|
await input.fill("India");
|
||||||
|
} else if (name?.includes("address")) {
|
||||||
|
await input.fill("123 Tech Park, Bangalore");
|
||||||
|
} else if (name?.includes("website")) {
|
||||||
|
await input.fill("https://testcompany.com");
|
||||||
|
} else if (name?.includes("industry")) {
|
||||||
|
await input.fill("Technology");
|
||||||
|
} else if (name?.includes("description") || name?.includes("about")) {
|
||||||
|
await input.fill(
|
||||||
|
"We are a technology company looking for talented professionals to join our team. We offer competitive salaries and a great work environment.",
|
||||||
|
);
|
||||||
|
} else if (type === "text" && !name?.includes("name")) {
|
||||||
|
// Fill any empty text fields
|
||||||
|
const value = await input.inputValue();
|
||||||
|
if (!value) {
|
||||||
|
await input.fill("Test Data");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {}
|
||||||
|
}
|
||||||
|
console.log(" ✅ Profile fields filled");
|
||||||
|
await page.waitForTimeout(2000);
|
||||||
|
|
||||||
|
// Step 7: Submit for verification
|
||||||
|
console.log("\n🚀 Step 7: Submitting profile for verification...");
|
||||||
|
const profileSubmitBtn = await page
|
||||||
|
.locator(
|
||||||
|
'button[type="submit"], button:has-text("Submit"), button:has-text("Save"), button:has-text("Continue")',
|
||||||
|
)
|
||||||
|
.first();
|
||||||
|
await profileSubmitBtn.click();
|
||||||
|
console.log("✅ Profile submitted");
|
||||||
|
await page.waitForTimeout(5000);
|
||||||
|
|
||||||
|
// Take screenshot
|
||||||
|
await page.screenshot({
|
||||||
|
path: "./test-results/after-profile-submit.png",
|
||||||
|
fullPage: true,
|
||||||
|
});
|
||||||
|
console.log("📸 Screenshot saved: after-profile-submit.png");
|
||||||
|
|
||||||
|
// Step 8: Open Admin Panel in new tab
|
||||||
|
console.log("\n🔐 Step 8: Opening admin panel...");
|
||||||
|
const adminPage = await context.newPage();
|
||||||
|
await adminPage.goto("http://localhost:3000/login");
|
||||||
|
await adminPage.waitForTimeout(3000);
|
||||||
|
|
||||||
|
// Admin login
|
||||||
|
console.log("🔑 Logging into admin panel...");
|
||||||
|
const adminEmailInput = await adminPage
|
||||||
|
.locator('input[type="email"], input[name="email"]')
|
||||||
|
.first();
|
||||||
|
await adminEmailInput.fill("admin@nxtgauge.com");
|
||||||
|
await adminPage.waitForTimeout(500);
|
||||||
|
|
||||||
|
const adminPasswordInput = await adminPage
|
||||||
|
.locator('input[type="password"]')
|
||||||
|
.first();
|
||||||
|
await adminPasswordInput.fill("admin123");
|
||||||
|
await adminPage.waitForTimeout(500);
|
||||||
|
|
||||||
|
const adminLoginBtn = await adminPage
|
||||||
|
.locator('button[type="submit"]')
|
||||||
|
.first();
|
||||||
|
await adminLoginBtn.click();
|
||||||
|
console.log("✅ Admin login submitted");
|
||||||
|
await adminPage.waitForTimeout(4000);
|
||||||
|
|
||||||
|
// Step 9: Navigate to Verifications
|
||||||
|
console.log("\n🔍 Step 9: Navigating to Verification Management...");
|
||||||
|
await adminPage.goto("http://localhost:3000/admin/verification");
|
||||||
|
await adminPage.waitForTimeout(4000);
|
||||||
|
|
||||||
|
// Step 10: Search for the company
|
||||||
|
console.log("\n🔎 Step 10: Searching for submitted company...");
|
||||||
|
const searchInput = await adminPage
|
||||||
|
.locator(
|
||||||
|
'input[type="search"], input[name="search"], input[placeholder*="search"]',
|
||||||
|
)
|
||||||
|
.first();
|
||||||
|
if (searchInput) {
|
||||||
|
await searchInput.fill(testCompanyName);
|
||||||
|
console.log(` ✅ Searching for: ${testCompanyName}`);
|
||||||
|
await adminPage.waitForTimeout(3000);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Take final screenshot
|
||||||
|
await adminPage.screenshot({
|
||||||
|
path: "./test-results/admin-verification.png",
|
||||||
|
fullPage: true,
|
||||||
|
});
|
||||||
|
console.log("📸 Screenshot saved: admin-verification.png");
|
||||||
|
|
||||||
|
// Check if company is found
|
||||||
|
const companyFound = await adminPage
|
||||||
|
.locator(`text=${testCompanyName}`)
|
||||||
|
.isVisible()
|
||||||
|
.catch(() => false);
|
||||||
|
if (companyFound) {
|
||||||
|
console.log(
|
||||||
|
"\n✅ SUCCESS! Company verification request found in admin panel!",
|
||||||
|
);
|
||||||
|
console.log(` Company: ${testCompanyName}`);
|
||||||
|
console.log(` Email: ${testEmail}`);
|
||||||
|
} else {
|
||||||
|
console.log("\n⚠️ Company not immediately visible. Check:");
|
||||||
|
console.log(" - Filters may need adjustment");
|
||||||
|
console.log(" - Verification may still be processing");
|
||||||
|
console.log(" - Try searching by email instead");
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("\n⏳ Keeping browser open for 20 seconds...");
|
||||||
|
console.log(" Screenshots saved in ./test-results/");
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, 20000));
|
||||||
|
} catch (error) {
|
||||||
|
console.error("\n❌ Error:", error.message);
|
||||||
|
await page.screenshot({ path: "./test-results/error.png", fullPage: true });
|
||||||
|
} finally {
|
||||||
|
await context.close();
|
||||||
|
await browser.close();
|
||||||
|
console.log("\n✅ Test completed");
|
||||||
|
}
|
||||||
|
})();
|
||||||
505
src/app.css
505
src/app.css
File diff suppressed because it is too large
Load diff
BIN
test-videos/5963f99d7049457dc44031f8de1b036e.webm
Normal file
BIN
test-videos/5963f99d7049457dc44031f8de1b036e.webm
Normal file
Binary file not shown.
BIN
test-videos/b1138b33a3072368fbf41afe386d65bf.webm
Normal file
BIN
test-videos/b1138b33a3072368fbf41afe386d65bf.webm
Normal file
Binary file not shown.
212
tests/e2e/company-verification-flow.spec.ts
Normal file
212
tests/e2e/company-verification-flow.spec.ts
Normal file
|
|
@ -0,0 +1,212 @@
|
||||||
|
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)}`;
|
||||||
|
|
||||||
|
console.log("🧪 Starting E2E Test Flow");
|
||||||
|
console.log("📧 Test Email:", testEmail);
|
||||||
|
console.log("🏢 Company Name:", testCompanyName);
|
||||||
|
|
||||||
|
test.setTimeout(120000);
|
||||||
|
|
||||||
|
test("Company signup -> verification flow", async () => {
|
||||||
|
// Launch browser with UI visible
|
||||||
|
const browser = await chromium.launch({
|
||||||
|
headless: false,
|
||||||
|
slowMo: 500, // Slow down for visibility
|
||||||
|
});
|
||||||
|
|
||||||
|
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...");
|
||||||
|
await page.goto("http://localhost:3001/signup");
|
||||||
|
await page.waitForLoadState("networkidle");
|
||||||
|
|
||||||
|
// Take screenshot of signup page
|
||||||
|
await page.screenshot({ path: "./test-results/01-signup-page.png", fullPage: true });
|
||||||
|
console.log("📸 Screenshot: Signup page");
|
||||||
|
|
||||||
|
// Step 2: Fill signup form
|
||||||
|
console.log("✍️ Step 2: Filling signup form...");
|
||||||
|
await page.fill('input[name="email"], input[type="email"]', testEmail);
|
||||||
|
await page.fill('input[name="password"], input[type="password"]', testPassword);
|
||||||
|
await page.fill('input[name="confirmPassword"], input[name="confirm"]', testPassword);
|
||||||
|
|
||||||
|
await page.screenshot({ path: "./test-results/02-signup-filled.png", fullPage: true });
|
||||||
|
console.log("📸 Screenshot: Signup form filled");
|
||||||
|
|
||||||
|
// Click signup button
|
||||||
|
await page.click('button[type="submit"], button:has-text("Sign")');
|
||||||
|
await page.waitForTimeout(3000);
|
||||||
|
|
||||||
|
await page.screenshot({ path: "./test-results/03-after-signup.png", fullPage: true });
|
||||||
|
console.log("📸 Screenshot: After signup");
|
||||||
|
|
||||||
|
// Step 3: Select Company role
|
||||||
|
console.log("🎯 Step 3: Selecting Company role...");
|
||||||
|
await page.waitForSelector("text=Company, text=company", { timeout: 10000 });
|
||||||
|
await page.click("text=Company");
|
||||||
|
await page.waitForTimeout(2000);
|
||||||
|
|
||||||
|
await page.screenshot({ path: "./test-results/04-company-selected.png", fullPage: true });
|
||||||
|
console.log("📸 Screenshot: Company role selected");
|
||||||
|
|
||||||
|
// Step 4: Fill Company Profile
|
||||||
|
console.log("📝 Step 4: Filling company profile...");
|
||||||
|
|
||||||
|
// Company name
|
||||||
|
await page.fill(
|
||||||
|
'input[name="companyName"], input[name="name"], input[placeholder*="company"]',
|
||||||
|
testCompanyName
|
||||||
|
);
|
||||||
|
|
||||||
|
// Business type
|
||||||
|
await page.selectOption('select[name="businessType"]', "Private Limited");
|
||||||
|
|
||||||
|
// Industry
|
||||||
|
await page.fill('input[name="industry"]', "Technology");
|
||||||
|
|
||||||
|
// Website
|
||||||
|
await page.fill('input[name="website"]', "https://testcompany.com");
|
||||||
|
|
||||||
|
// Description
|
||||||
|
await page.fill(
|
||||||
|
'textarea[name="description"], textarea[name="about"]',
|
||||||
|
"We are a technology company looking for talented professionals to join our team."
|
||||||
|
);
|
||||||
|
|
||||||
|
await page.screenshot({ path: "./test-results/05-profile-filled.png", fullPage: true });
|
||||||
|
console.log("📸 Screenshot: Profile details filled");
|
||||||
|
|
||||||
|
// Contact details
|
||||||
|
await page.fill('input[name="contactName"]', "John Doe");
|
||||||
|
await page.fill('input[name="contactEmail"]', testEmail);
|
||||||
|
await page.fill('input[name="contactPhone"]', "+91 9876543210");
|
||||||
|
|
||||||
|
// Address
|
||||||
|
await page.fill('input[name="address"], textarea[name="address"]', "123 Tech Park, Bangalore");
|
||||||
|
await page.fill('input[name="city"]', "Bangalore");
|
||||||
|
await page.fill('input[name="state"]', "Karnataka");
|
||||||
|
await page.fill('input[name="country"]', "India");
|
||||||
|
await page.fill('input[name="postalCode"]', "560001");
|
||||||
|
|
||||||
|
await page.screenshot({ path: "./test-results/06-contact-filled.png", fullPage: true });
|
||||||
|
console.log("📸 Screenshot: Contact details filled");
|
||||||
|
|
||||||
|
// Step 5: Submit for verification
|
||||||
|
console.log("🚀 Step 5: Submitting for verification...");
|
||||||
|
await page.click('button[type="submit"], button:has-text("Submit"), button:has-text("Save")');
|
||||||
|
await page.waitForTimeout(3000);
|
||||||
|
|
||||||
|
await page.screenshot({ path: "./test-results/07-profile-submitted.png", fullPage: true });
|
||||||
|
console.log("📸 Screenshot: Profile submitted");
|
||||||
|
|
||||||
|
// Wait for verification status page
|
||||||
|
await page.waitForSelector("text=verification, text=Verification, text=status", {
|
||||||
|
timeout: 10000,
|
||||||
|
});
|
||||||
|
|
||||||
|
await page.screenshot({ path: "./test-results/08-verification-status.png", fullPage: true });
|
||||||
|
console.log("📸 Screenshot: Verification status page");
|
||||||
|
|
||||||
|
// Step 6: Open Admin Panel
|
||||||
|
console.log("🔐 Step 6: 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/09-admin-login.png", fullPage: true });
|
||||||
|
console.log("📸 Screenshot: Admin login page");
|
||||||
|
|
||||||
|
// Admin login (assuming default admin credentials)
|
||||||
|
// Note: You may need to adjust these credentials
|
||||||
|
await adminPage.fill('input[name="email"], input[type="email"]', "admin@nxtgauge.com");
|
||||||
|
await adminPage.fill('input[name="password"], input[type="password"]', "admin123");
|
||||||
|
|
||||||
|
await adminPage.click(
|
||||||
|
'button[type="submit"], button:has-text("Login"), button:has-text("Sign In")'
|
||||||
|
);
|
||||||
|
await adminPage.waitForTimeout(3000);
|
||||||
|
|
||||||
|
await adminPage.screenshot({ path: "./test-results/10-admin-logged-in.png", fullPage: true });
|
||||||
|
console.log("📸 Screenshot: Admin logged in");
|
||||||
|
|
||||||
|
// Step 7: Navigate to Verification Management
|
||||||
|
console.log("🔍 Step 7: Navigating to Verification Management...");
|
||||||
|
|
||||||
|
// Click on Verifications in sidebar
|
||||||
|
await adminPage.click(
|
||||||
|
'text=Verifications, a:has-text("Verifications"), [href*="verification"]'
|
||||||
|
);
|
||||||
|
await adminPage.waitForTimeout(3000);
|
||||||
|
|
||||||
|
await adminPage.screenshot({ path: "./test-results/11-verification-list.png", fullPage: true });
|
||||||
|
console.log("📸 Screenshot: Verification list page");
|
||||||
|
|
||||||
|
// Step 8: Check if our company appears in verification queue
|
||||||
|
console.log("🔎 Step 8: Checking for company verification request...");
|
||||||
|
|
||||||
|
// Search for the company name
|
||||||
|
await adminPage.fill('input[placeholder*="search"], input[name="search"]', testCompanyName);
|
||||||
|
await adminPage.waitForTimeout(2000);
|
||||||
|
|
||||||
|
await adminPage.screenshot({ path: "./test-results/12-search-results.png", fullPage: true });
|
||||||
|
console.log("📸 Screenshot: Search results");
|
||||||
|
|
||||||
|
// Check if company is found
|
||||||
|
const companyFound = await adminPage
|
||||||
|
.locator(`text=${testCompanyName}`)
|
||||||
|
.isVisible()
|
||||||
|
.catch(() => false);
|
||||||
|
|
||||||
|
if (companyFound) {
|
||||||
|
console.log("✅ SUCCESS: Company verification request found in admin panel!");
|
||||||
|
|
||||||
|
// Click on the company to view details
|
||||||
|
await adminPage.click(`text=${testCompanyName}`);
|
||||||
|
await adminPage.waitForTimeout(3000);
|
||||||
|
|
||||||
|
await adminPage.screenshot({ path: "./test-results/13-company-details.png", fullPage: true });
|
||||||
|
console.log("📸 Screenshot: Company verification details");
|
||||||
|
|
||||||
|
// Verify the details match what we submitted
|
||||||
|
await expect(adminPage.locator("body")).toContainText(testEmail);
|
||||||
|
await expect(adminPage.locator("body")).toContainText("Bangalore");
|
||||||
|
|
||||||
|
console.log("✅ All verification details match!");
|
||||||
|
} else {
|
||||||
|
console.log("⚠️ Company not found in verification queue");
|
||||||
|
console.log(" This might be because:");
|
||||||
|
console.log(" - The profile is still being processed");
|
||||||
|
console.log(" - The verification queue filters are different");
|
||||||
|
console.log(" - The admin credentials are incorrect");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keep browser open for 10 seconds to show results
|
||||||
|
console.log("⏳ Keeping browser open for 10 seconds...");
|
||||||
|
await page.waitForTimeout(10000);
|
||||||
|
} 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("✅ Test completed!");
|
||||||
|
console.log("📹 Video saved to: ./test-videos/");
|
||||||
|
console.log("📸 Screenshots saved to: ./test-results/");
|
||||||
|
}
|
||||||
|
});
|
||||||
Loading…
Add table
Reference in a new issue