From 0c8d9ea66909734a3a7be487cd51a701dc1c8809 Mon Sep 17 00:00:00 2001 From: Marc Mintel Date: Sun, 1 Mar 2026 16:03:23 +0100 Subject: [PATCH] fix(e2e): await hydration before form submits, skip cleanup on 403 fix(blog): bypass image optimization for post feature image chore(release): bump version to 2.2.7 --- app/[locale]/blog/[slug]/page.tsx | 30 ++++++++++++++++-------------- package.json | 2 +- scripts/check-forms.ts | 25 +++++++++++++++++++++---- 3 files changed, 38 insertions(+), 19 deletions(-) diff --git a/app/[locale]/blog/[slug]/page.tsx b/app/[locale]/blog/[slug]/page.tsx index de41a62c..4fbc849c 100644 --- a/app/[locale]/blog/[slug]/page.tsx +++ b/app/[locale]/blog/[slug]/page.tsx @@ -98,6 +98,8 @@ export default async function BlogPost({ params }: BlogPostProps) { alt={post.frontmatter.title} fill priority + quality={100} + unoptimized={true} className="object-cover" sizes="100vw" style={{ @@ -133,13 +135,13 @@ export default async function BlogPost({ params }: BlogPostProps) { {getReadingTime(rawTextContent)} min read {(new Date(post.frontmatter.date) > new Date() || post.frontmatter.public === false) && ( - <> - - - Draft Preview - - - )} + <> + + + Draft Preview + + + )} @@ -170,13 +172,13 @@ export default async function BlogPost({ params }: BlogPostProps) { {getReadingTime(rawTextContent)} min read {(new Date(post.frontmatter.date) > new Date() || post.frontmatter.public === false) && ( - <> - - - Draft Preview - - - )} + <> + + + Draft Preview + + + )} diff --git a/package.json b/package.json index b95cfd79..02f76002 100644 --- a/package.json +++ b/package.json @@ -139,7 +139,7 @@ "prepare": "husky", "preinstall": "npx only-allow pnpm" }, - "version": "2.2.6", + "version": "2.2.7", "pnpm": { "onlyBuiltDependencies": [ "@parcel/watcher", diff --git a/scripts/check-forms.ts b/scripts/check-forms.ts index b88edae2..5ac6e209 100644 --- a/scripts/check-forms.ts +++ b/scripts/check-forms.ts @@ -98,7 +98,7 @@ async function main() { await page.goto(contactUrl, { waitUntil: 'networkidle0', timeout: 30000 }); // 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 try { @@ -109,6 +109,9 @@ async function main() { throw e; } + // Wait specifically for hydration logic to initialize the onSubmit handler + await page.evaluate(() => new Promise((resolve) => setTimeout(resolve, 2000))); + // Fill form fields await page.type('input[name="name"]', 'Automated E2E Test'); 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.', ); + // Give state a moment to settle + await page.evaluate(() => new Promise((resolve) => setTimeout(resolve, 500))); + console.log(` Submitting Contact Form...`); // Explicitly click submit and wait for navigation/state-change @@ -137,7 +143,7 @@ async function main() { await page.goto(productUrl, { waitUntil: 'networkidle0', timeout: 30000 }); // 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 try { @@ -147,6 +153,9 @@ async function main() { 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. await page.type('form input[type="email"]', 'testing@mintel.me'); await page.type( @@ -154,6 +163,9 @@ async function main() { '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...`); // Submit and wait for success state @@ -189,11 +201,16 @@ async function main() { }); console.log(` ✅ Deleted submission: ${doc.id}`); } 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) { - 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 }