const Helper = require("@codeceptjs/helper"); const getPage = (h) => { return (h.Puppeteer ?? h.Playwright).page; }; class Selection extends Helper { async dblClickOnWord(text, parent = "*") { const page = getPage(this.helpers); const { mouse } = page; const xpath = [locate(parent).toXPath(), `//text()[contains(., '${text}')]`, "[last()]"].join(""); const point = await page.evaluate( ({ xpath, text }) => { const textEl = document.evaluate(xpath, document, null, XPathResult.ANY_TYPE, null).iterateNext(); const pos = textEl.wholeText.search(text); const range = new Range(); range.setStart(textEl, pos); range.setEnd(textEl, pos + 1); const bbox = range.getBoundingClientRect(); return { x: (bbox.left + bbox.right) / 2, y: (bbox.top + bbox.bottom) / 2, }; }, { xpath, text }, ); return mouse.click(point.x, point.y, { button: "left", clickCount: 2, delay: 50 }); } async dblClickOnElement(elementLocator) { const page = getPage(this.helpers); const { mouse } = page; const elsXpath = locate(elementLocator).toXPath(); const point = await page.evaluate((elsXpath) => { const el = document.evaluate(elsXpath, document, null, XPathResult.ANY_TYPE, null).iterateNext(); const bbox = el.getBoundingClientRect(); return { x: (bbox.left + bbox.right) / 2, y: (bbox.top + bbox.bottom) / 2, }; }, elsXpath); return mouse.click(point.x, point.y, { button: "left", clickCount: 2, delay: 50 }); } async setSelection(startLocator, startOffset, endLocator, endOffset) { const page = getPage(this.helpers); const startContainerXPath = locate(startLocator).toXPath(); const endContainerXPath = locate(endLocator).toXPath(); await page.evaluate( ({ startContainerXPath, startOffset, endContainerXPath, endOffset }) => { const startContainer = document .evaluate(startContainerXPath, document, null, XPathResult.ANY_TYPE, null) .iterateNext(); const endContainer = document .evaluate(endContainerXPath, document, null, XPathResult.ANY_TYPE, null) .iterateNext(); const range = new Range(); range.setStart(startContainer, startOffset); range.setEnd(endContainer, endOffset); const selection = window.getSelection(); selection.removeAllRanges(); selection.addRange(range); const evt = new MouseEvent("mouseup"); evt.initMouseEvent("mouseup", true, true); endContainer.dispatchEvent(evt); }, { startContainerXPath, startOffset, endContainerXPath, endOffset }, ); } } module.exports = Selection;