[object Object]

← back to Pattern Vault

spoonflower: proven filechooser selector + network-block consent vendors + iframe-aware dismiss + deep DOM diagnostic; next blocker = file doesn't register post-filechooser (needs headed session)

7fb0d68686f63e71232a96d4094c772bc9f1d075 · 2026-07-09 18:13:14 -0700 · Steve

Files touched

Diff

commit 7fb0d68686f63e71232a96d4094c772bc9f1d075
Author: Steve <steve@designerwallcoverings.com>
Date:   Thu Jul 9 18:13:14 2026 -0700

    spoonflower: proven filechooser selector + network-block consent vendors + iframe-aware dismiss + deep DOM diagnostic; next blocker = file doesn't register post-filechooser (needs headed session)
---
 whimsical-compare/daily/scripts/upload_sf.js | 30 +++++++++++++++++++++-------
 1 file changed, 23 insertions(+), 7 deletions(-)

diff --git a/whimsical-compare/daily/scripts/upload_sf.js b/whimsical-compare/daily/scripts/upload_sf.js
index 2ebb1b4..fd788ac 100755
--- a/whimsical-compare/daily/scripts/upload_sf.js
+++ b/whimsical-compare/daily/scripts/upload_sf.js
@@ -68,8 +68,30 @@ async function messyType(el, text) {
 
   const b = await chromium.launch({ headless: (process.env.SF_HEADLESS === '1') ? true : !ARMED, args: ['--start-maximized'] });
   const ctx = await b.newContext({ viewport: ARMED ? null : { width: 1400, height: 900 }, storageState: STATE, userAgent: UA });
+  // DIAGNOSED 2026-07-09: an intermittent consent/marketing overlay (bounceexchange iframe +
+  // "Your Privacy Choices / Agree & Continue") intercepts the uploader clicks. Block those
+  // vendors at the network layer so the overlay never loads. (Spoonflower's own uploader is unaffected.)
+  await ctx.route('**/*', (route) => {
+    const u = route.request().url();
+    if (/bounceexchange\.com|bounce\.|onetrust|cookielaw|osano|consent|quantcast|trustarc/i.test(u)) return route.abort();
+    return route.continue();
+  }).catch(() => {});
   const pg = await ctx.newPage();
 
+  // iframe-aware consent dismissal — the "Agree & Continue" button lives in an iframe, so scan
+  // every frame (not just the top document) and click it wherever it is.
+  async function dismissConsent() {
+    for (const fr of pg.frames()) {
+      for (const sel of ['button:has-text("Agree & Continue")', 'button:has-text("Accept All")',
+                         'button:has-text("Accept")', 'button:has-text("I Agree")', 'text="Agree & Continue"',
+                         '#onetrust-accept-btn-handler']) {
+        const el = await fr.$(sel).catch(() => null);
+        if (el) { await el.click().catch(() => {}); await sleep(rnd(500, 1100)); return true; }
+      }
+    }
+    return false;
+  }
+
   // session health check
   await pg.goto('https://www.spoonflower.com/en/my_account', { waitUntil: 'domcontentloaded', timeout: 45000 }).catch(() => {});
   await sleep(2500);
@@ -113,13 +135,7 @@ async function messyType(el, text) {
       if (!ARMED) { result.uploaded.push({ title: d.title, dryRun: true, id: null, url: null }); await sleep(rnd(600, 1200)); continue; }
 
       // ---- ARMED: real upload ----
-      // Dismiss any consent/privacy overlay first — it intercepts the uploader clicks.
-      // DIAGNOSED 2026-07-09: a "Your Privacy Choices → Agree & Continue" modal ate the click.
-      for (const sel of ['button:has-text("Agree & Continue")', 'button:has-text("Accept All")',
-                         'button:has-text("Accept")', 'button:has-text("I Agree")', '#onetrust-accept-btn-handler']) {
-        const c = await pg.$(sel);
-        if (c) { await c.click().catch(() => {}); await sleep(rnd(700, 1500)); break; }
-      }
+      await dismissConsent(); // iframe-aware; overlay is also network-blocked at context level
 
       // Drive the REAL uploader via the "Choose Files" button + native filechooser.
       // DIAGNOSED 2026-07-09: setInputFiles() on the hidden input is a NO-OP against

← 45745d8 auto-save: 2026-07-09T18:11:36 (2 files) — whimsical-compare  ·  back to Pattern Vault  ·  wpb-uploaders: Etsy createDraftListing payload mapping + --d 6662111 →