diff --git a/scratch/inspect-meez-page-layout.cjs b/scratch/inspect-meez-page-layout.cjs new file mode 100644 index 0000000..22d05d3 --- /dev/null +++ b/scratch/inspect-meez-page-layout.cjs @@ -0,0 +1,98 @@ +const fs = require('fs'); + +async function main() { + const pages = await fetch('http://localhost:9222/json').then(r => r.json()); + const meezPage = pages.find(p => p.url.includes('getmeez.com/recipes/')); + if (!meezPage) return console.log('No recipe page found'); + + const ws = new WebSocket(meezPage.webSocketDebuggerUrl); + let id = 1; + const send = (method, params = {}) => new Promise((resolve, reject) => { + const msgId = id++; + const handler = (event) => { + const res = JSON.parse(event.data); + if (res.id === msgId) { + ws.removeEventListener('message', handler); + if (res.error) reject(res.error); + else resolve(res.result); + } + }; + ws.addEventListener('message', handler); + ws.send(JSON.stringify({ id: msgId, method, params })); + }); + + ws.addEventListener('open', async () => { + try { + const evalRes = await send('Runtime.evaluate', { + expression: `(() => { + const metaItem = document.querySelector('[data-testid="metaItem"]'); + if (!metaItem) return { error: 'metaItem not found' }; + + const rect = metaItem.getBoundingClientRect(); + const parent = metaItem.parentElement; + const grandParent = parent ? parent.parentElement : null; + + // Find recipe title + const title = document.querySelector('h1, [data-testid*="title"], [data-testid*="Title"]'); + const titleRect = title ? title.getBoundingClientRect() : null; + + // Find ingredients table / container + const ingContainer = document.querySelector('[data-testid*="Ingredients"], [data-testid*="RecipeTable"], table, [role="table"]'); + const ingRect = ingContainer ? ingContainer.getBoundingClientRect() : null; + + // Collect siblings of metaItem + const siblings = parent ? Array.from(parent.children).map(c => ({ + tag: c.tagName, + class: c.className, + testId: c.getAttribute('data-testid'), + rect: c.getBoundingClientRect(), + text: c.innerText?.slice(0, 100) + })) : []; + + // Collect ancestors up to body + const ancestors = []; + let cur = metaItem; + while (cur && cur !== document.body) { + ancestors.push({ + tag: cur.tagName, + class: cur.className, + testId: cur.getAttribute('data-testid'), + rect: cur.getBoundingClientRect(), + style: { + display: window.getComputedStyle(cur).display, + position: window.getComputedStyle(cur).position, + padding: window.getComputedStyle(cur).padding, + margin: window.getComputedStyle(cur).margin, + gap: window.getComputedStyle(cur).gap + } + }); + cur = cur.parentElement; + } + + return { + metaItemRect: rect, + titleRect, + ingRect, + titleHtml: title?.outerHTML, + parentHtml: parent?.outerHTML?.slice(0, 500), + siblings, + ancestors + }; + })()`, + returnByValue: true + }); + + fs.writeFileSync('scratch/meez_page_layout.json', JSON.stringify(evalRes.result.value, null, 2)); + console.log('Saved to scratch/meez_page_layout.json'); + console.log('Ancestors count:', evalRes.result.value.ancestors?.length); + console.log('Siblings:\n', evalRes.result.value.siblings?.map(s => `${s.tag} (${s.testId || s.class}): ${s.text?.slice(0, 40)}`)); + + ws.close(); + } catch (e) { + console.error(e); + ws.close(); + } + }); +} + +main().catch(console.error); diff --git a/scratch/inspect-meez-structure.cjs b/scratch/inspect-meez-structure.cjs new file mode 100644 index 0000000..7a3898e --- /dev/null +++ b/scratch/inspect-meez-structure.cjs @@ -0,0 +1,74 @@ +const fs = require('fs'); + +async function main() { + const pages = await fetch('http://localhost:9222/json').then(r => r.json()); + const meezPage = pages.find(p => p.url.includes('getmeez.com/recipes/')); + if (!meezPage) return console.log('No recipe page found'); + + const ws = new WebSocket(meezPage.webSocketDebuggerUrl); + let id = 1; + const send = (method, params = {}) => new Promise((resolve, reject) => { + const msgId = id++; + const handler = (event) => { + const res = JSON.parse(event.data); + if (res.id === msgId) { + ws.removeEventListener('message', handler); + if (res.error) reject(res.error); + else resolve(res.result); + } + }; + ws.addEventListener('message', handler); + ws.send(JSON.stringify({ id: msgId, method, params })); + }); + + ws.addEventListener('open', async () => { + try { + const evalRes = await send('Runtime.evaluate', { + expression: `(() => { + // Get the entire recipe layout tree from the main container + const main = document.querySelector('[data-testid="RoutesBase"]') || document.querySelector('main') || document.querySelector('#root'); + + const header = document.querySelector('[data-testid*="Header"], header'); + const title = document.querySelector('h1, [data-testid*="EditableEntityNameBase_name"]'); + const titleParent = title ? title.closest('[data-testid*="Header"], div') : null; + + return { + titleParentHtml: titleParent ? { + tag: titleParent.tagName, + class: titleParent.className, + testId: titleParent.getAttribute('data-testid'), + html: titleParent.outerHTML, + style: { + padding: window.getComputedStyle(titleParent).padding, + margin: window.getComputedStyle(titleParent).margin + } + } : null, + leftColumnChildren: (() => { + const leftCol = document.querySelector('[data-testid="RoutesBase_section"]'); + if (!leftCol) return null; + return Array.from(leftCol.children).map(c => ({ + tag: c.tagName, + class: c.className, + testId: c.getAttribute('data-testid'), + text: c.innerText?.slice(0, 80), + html: c.outerHTML.slice(0, 200) + })); + })() + }; + })()`, + returnByValue: true + }); + + fs.writeFileSync('scratch/meez_structure.json', JSON.stringify(evalRes.result.value, null, 2)); + console.log('Structure saved.'); + console.log(JSON.stringify(evalRes.result.value, null, 2)); + + ws.close(); + } catch (e) { + console.error(e); + ws.close(); + } + }); +} + +main().catch(console.error); diff --git a/scratch/meez_page_layout.json b/scratch/meez_page_layout.json new file mode 100644 index 0000000..55e50e4 --- /dev/null +++ b/scratch/meez_page_layout.json @@ -0,0 +1,148 @@ +{ + "metaItemRect": {}, + "titleRect": {}, + "ingRect": {}, + "titleHtml": "