import {chromium} from 'playwright'; const b = await chromium.launch({channel: 'chrome'}); const page = await b.newPage({viewport: {width: 1280, height: 900}}); const logs = []; page.on('console', (m) => { if (m.text().includes('[w4d]') || m.type() === 'error') logs.push(`${m.type()}: ${m.text().slice(0,110)}`); }); await page.goto('http://localhost/s/stay', {waitUntil: 'domcontentloaded'}); await page.waitForTimeout(6000); const r = await page.evaluate(() => { const txt = (el) => (el?.textContent || '').trim(); const songTitles = [...document.querySelectorAll('#songs .w4d-t, #songs button span')].map(txt).filter(Boolean); return { mini: !!document.getElementById('w4d-mini'), tape: !!document.getElementById('w4d-tape'), miniBtns: document.querySelectorAll('#w4d-mini button').length, songsCount: document.querySelectorAll('#songs button[aria-pressed]').length, songsHasOwn: document.body.innerHTML.includes('머뭄의 아침') && !!document.querySelector('#songs'), ownInSection: [...document.querySelectorAll('#songs')].some((s) => s.textContent.includes('Stay in 머뭄')), people: document.querySelectorAll('#people article').length, itinLinks: document.querySelectorAll('#itinerary a.w4d-link').length, postcardLinks: document.querySelectorAll('#postcard a.w4d-link').length, itinImgs: document.querySelectorAll('#itinerary img:not([src*="openstreetmap"])').length, firstStops: [...document.querySelectorAll('#itinerary article')].slice(0, 6).map((a) => txt(a.querySelector('ol li span'))), bbq: document.body.textContent.includes('바비큐'), redRule: document.querySelectorAll('.w4d-rule').length, }; }); console.log(JSON.stringify(r, null, 1)); const sample = await page.evaluate(() => { const a = document.querySelector('#itinerary a.w4d-link'); const p = document.querySelector('#postcard a.w4d-link'); return {itin: a?.getAttribute('href'), postcard: p?.getAttribute('href')}; }); console.log('링크 샘플', JSON.stringify(sample)); console.log(logs.join('\n')); await page.screenshot({path: '/tmp/v-itin.png', clip: {x: 0, y: 0, width: 1280, height: 900}}); await b.close();