const { chromium, devices } = require('playwright'); (async () => { const browser = await chromium.launch({ headless: true }); const iPhone = devices['iPhone 12']; const context = await browser.newContext({ ...iPhone }); await context.addInitScript(() => { localStorage.setItem('ka-note-browser-key', 'dev-test-bypass-key'); }); const page = await context.newPage(); // Capture console messages from the page page.on('console', msg => console.log('[page]', msg.text())); await page.goto('http://localhost:5173'); await page.waitForLoadState('networkidle'); await page.waitForTimeout(2000); const editor = page.locator('.ProseMirror').first(); await editor.waitFor({ state: 'visible', timeout: 5000 }); // Type some text first, then tap without selecting await editor.tap(); await page.waitForTimeout(300); await page.keyboard.type('Test text for bubble menu bug'); await page.waitForTimeout(500); await page.screenshot({ path: 'C:/work/chrka/myNote/with-text.png' }); // Now tap somewhere to deselect await page.tap('body', { position: { x: 10, y: 10 } }); await page.waitForTimeout(300); // Tap into editor again (single tap, no selection) await editor.tap(); await page.waitForTimeout(800); await page.screenshot({ path: 'C:/work/chrka/myNote/after-tap-with-text.png' }); // Inspect tippy wrapper visibility via JS const tippyState = await page.evaluate(() => { const boxes = document.querySelectorAll('.tippy-box'); const bubbles = document.querySelectorAll('.ka-bubble-menu'); const tippyRoots = document.querySelectorAll('[data-tippy-root]'); return { tippyBoxCount: boxes.length, kaBubbleCount: bubbles.length, tippyRootCount: tippyRoots.length, tippyRoots: Array.from(tippyRoots).map(el => ({ display: window.getComputedStyle(el).display, visibility: window.getComputedStyle(el).visibility, opacity: window.getComputedStyle(el).opacity, innerHTML: el.innerHTML.substring(0, 100) })), kaBubbles: Array.from(bubbles).map(el => ({ display: window.getComputedStyle(el).display, visibility: window.getComputedStyle(el).visibility, opacity: window.getComputedStyle(el).opacity, parentDisplay: el.parentElement ? window.getComputedStyle(el.parentElement).display : 'no parent', parentVisibility: el.parentElement ? window.getComputedStyle(el.parentElement).visibility : 'no parent', })) }; }); console.log('DOM state after tap with text:'); console.log(JSON.stringify(tippyState, null, 2)); // Check selection state const selectionState = await page.evaluate(() => { const sel = window.getSelection(); return { type: sel?.type, toString: sel?.toString(), rangeCount: sel?.rangeCount }; }); console.log('Selection state:', JSON.stringify(selectionState)); await browser.close(); })();