|
|
|
@@ -98,7 +98,7 @@ async function main() {
|
|
|
|
await page.goto(contactUrl, { waitUntil: 'networkidle0', timeout: 30000 });
|
|
|
|
await page.goto(contactUrl, { waitUntil: 'networkidle0', timeout: 30000 });
|
|
|
|
|
|
|
|
|
|
|
|
// Ensure React has hydrated completely
|
|
|
|
// Ensure React has hydrated completely
|
|
|
|
await page.waitForNetworkIdle({ idleTime: 1000, timeout: 15000 }).catch(() => {});
|
|
|
|
await page.waitForNetworkIdle({ idleTime: 1000, timeout: 15000 }).catch(() => { });
|
|
|
|
|
|
|
|
|
|
|
|
// Ensure form is visible and interactive
|
|
|
|
// Ensure form is visible and interactive
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
@@ -109,6 +109,9 @@ async function main() {
|
|
|
|
throw e;
|
|
|
|
throw e;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Wait specifically for hydration logic to initialize the onSubmit handler
|
|
|
|
|
|
|
|
await page.evaluate(() => new Promise((resolve) => setTimeout(resolve, 2000)));
|
|
|
|
|
|
|
|
|
|
|
|
// Fill form fields
|
|
|
|
// Fill form fields
|
|
|
|
await page.type('input[name="name"]', 'Automated E2E Test');
|
|
|
|
await page.type('input[name="name"]', 'Automated E2E Test');
|
|
|
|
await page.type('input[name="email"]', 'testing@mintel.me');
|
|
|
|
await page.type('input[name="email"]', 'testing@mintel.me');
|
|
|
|
@@ -117,6 +120,9 @@ async function main() {
|
|
|
|
'This is an automated test verifying the contact form submission.',
|
|
|
|
'This is an automated test verifying the contact form submission.',
|
|
|
|
);
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Give state a moment to settle
|
|
|
|
|
|
|
|
await page.evaluate(() => new Promise((resolve) => setTimeout(resolve, 500)));
|
|
|
|
|
|
|
|
|
|
|
|
console.log(` Submitting Contact Form...`);
|
|
|
|
console.log(` Submitting Contact Form...`);
|
|
|
|
|
|
|
|
|
|
|
|
// Explicitly click submit and wait for navigation/state-change
|
|
|
|
// Explicitly click submit and wait for navigation/state-change
|
|
|
|
@@ -137,7 +143,7 @@ async function main() {
|
|
|
|
await page.goto(productUrl, { waitUntil: 'networkidle0', timeout: 30000 });
|
|
|
|
await page.goto(productUrl, { waitUntil: 'networkidle0', timeout: 30000 });
|
|
|
|
|
|
|
|
|
|
|
|
// Ensure React has hydrated completely
|
|
|
|
// Ensure React has hydrated completely
|
|
|
|
await page.waitForNetworkIdle({ idleTime: 1000, timeout: 15000 }).catch(() => {});
|
|
|
|
await page.waitForNetworkIdle({ idleTime: 1000, timeout: 15000 }).catch(() => { });
|
|
|
|
|
|
|
|
|
|
|
|
// The product form uses dynamic IDs, so we select by input type in the specific form context
|
|
|
|
// The product form uses dynamic IDs, so we select by input type in the specific form context
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
@@ -147,6 +153,9 @@ async function main() {
|
|
|
|
throw e;
|
|
|
|
throw e;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Wait specifically for hydration logic to initialize the onSubmit handler
|
|
|
|
|
|
|
|
await page.evaluate(() => new Promise((resolve) => setTimeout(resolve, 2000)));
|
|
|
|
|
|
|
|
|
|
|
|
// In RequestQuoteForm, the email input is type="email" and message is a textarea.
|
|
|
|
// In RequestQuoteForm, the email input is type="email" and message is a textarea.
|
|
|
|
await page.type('form input[type="email"]', 'testing@mintel.me');
|
|
|
|
await page.type('form input[type="email"]', 'testing@mintel.me');
|
|
|
|
await page.type(
|
|
|
|
await page.type(
|
|
|
|
@@ -154,6 +163,9 @@ async function main() {
|
|
|
|
'Automated request for product quote via E2E testing framework.',
|
|
|
|
'Automated request for product quote via E2E testing framework.',
|
|
|
|
);
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Give state a moment to settle
|
|
|
|
|
|
|
|
await page.evaluate(() => new Promise((resolve) => setTimeout(resolve, 500)));
|
|
|
|
|
|
|
|
|
|
|
|
console.log(` Submitting Product Quote Form...`);
|
|
|
|
console.log(` Submitting Product Quote Form...`);
|
|
|
|
|
|
|
|
|
|
|
|
// Submit and wait for success state
|
|
|
|
// Submit and wait for success state
|
|
|
|
@@ -189,11 +201,16 @@ async function main() {
|
|
|
|
});
|
|
|
|
});
|
|
|
|
console.log(` ✅ Deleted submission: ${doc.id}`);
|
|
|
|
console.log(` ✅ Deleted submission: ${doc.id}`);
|
|
|
|
} catch (delErr: any) {
|
|
|
|
} catch (delErr: any) {
|
|
|
|
console.error(` ❌ Failed to delete submission ${doc.id}: ${delErr.message}`);
|
|
|
|
// Log but don't fail, 403s on Directus / Payload APIs for guest Gatekeeper sessions are normal
|
|
|
|
|
|
|
|
console.warn(` ⚠️ Cleanup attempt on ${doc.id} returned an error, typically due to API Auth separation: ${delErr.message}`);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} catch (err: any) {
|
|
|
|
} catch (err: any) {
|
|
|
|
console.error(`❌ Cleanup failed: ${err.message}`);
|
|
|
|
if (err.response?.status === 403) {
|
|
|
|
|
|
|
|
console.warn(` ⚠️ Cleanup fetch failed with 403 Forbidden. This is expected if the runner lacks admin API credentials. Test submissions remain in the database.`);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
console.error(` ❌ Cleanup fetch failed: ${err.message}`);
|
|
|
|
|
|
|
|
}
|
|
|
|
// Don't mark the whole test as failed just because cleanup failed
|
|
|
|
// Don't mark the whole test as failed just because cleanup failed
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|