ACTUALIZAR:
Después de investigar un poco más, me di cuenta de que puedo hacer esta pregunta de una manera más específica: ¿Cómo envío una gran cantidad de texto a un elemento contenteditable="true" ?
Estoy trabajando con un sitio web que tiene una API pero no tiene puntos finales que puedan editar contenido. Esta limitación de la API impide que se automatice mi proceso de lanzamiento. Como solución alternativa, he intentado automatizar las tareas con un navegador sin interfaz.
Una de estas tareas consiste en editar el contenido en un editor de texto enriquecido. Este editor de texto enriquecido no tiene ningún elemento de input , por lo que no es tan simple como cambiar el valor de algo. El HTML se parece a esto:
Puede consultar la fuente de este editor de texto enriquecido aquí: https://www.slatejs.org/examples/richtext
Intenté usar un código de titiritero (no me importa si la solución a esta respuesta es titiritero o no) para resolver este problema. Funciona, pero es demasiado lento: tengo 30k de texto para enviar al editor, así que await page.keyboard.type(stdin, {delay: 0}); tarda más de diez minutos en ejecutarse. Aquí está mi código:
export const edit = async () => { const browser = await launch({ headless: false }); const page = await browser.newPage(); try { await page.setUserAgent( 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:93.0) Gecko/20100101 Firefox/93.0' ); await page.goto('https://www.slatejs.org/examples/richtext'); await page.waitForSelector('[data-slate-string="true"]'); await page.click('[data-slate-string="true"]'); // select all await page.keyboard.down('Control'); await page.keyboard.press('a'); await page.keyboard.up('Control'); // clear everything in the rich text editor await page.keyboard.press('Backspace'); // type in new content await page.keyboard.type(aLargeAmountOfText, {delay: 0}); // this takes over 10 minutes! } finally { await page.screenshot({ path: 'example.png' }); await browser.close(); } };Una cosa que funcionaría (en teoría) es automatizar el copiar y pegar el texto en el editor. Realmente no quiero ir por este camino, porque tiendo a hacer otras cosas mientras me libero. Si mi secuencia de comandos modifica mi portapapeles (o yo lo modifico) mientras se está ejecutando, podría tener resultados impredecibles.
¿Cuál es la forma más rápida de enviar una gran cantidad de texto a un editor de texto enriquecido que no tiene elementos input ? No me importa qué herramienta de automatización se use (preferiría node.js, si es posible) o qué trucos debo usar, siempre que pueda descubrir cómo responder a esta pregunta.
Puede intentarlo con page.$eval :
export const edit = async () => { const browser = await launch({ headless: false }); const page = await browser.newPage(); try { await page.setUserAgent( 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:93.0) Gecko/20100101 Firefox/93.0' ); await page.goto('https://www.slatejs.org/examples/richtext'); await page.waitForSelector('[contenteditable="true"]'); await page.$eval('[contenteditable="true"]', (e) => e.textContent = aLargeAmountOfText); } finally { await page.screenshot({ path: 'example.png' }); await browser.close(); } };OK, esto fue tan difícil de entender. Aquí está:
await page.goto(url); const richTextEditorSelector = '[contenteditable="true"]'; await page.waitForSelector(richTextEditorSelector); await page.focus(richTextEditorSelector); // select all await page.evaluate(() => { return Promise.resolve(document.execCommand('selectAll')); }); const pasteReplacementText = ` const dataTransfer = new DataTransfer(); function dispatchPaste(target) { // this may be 'text/html' if it's required dataTransfer.setData('text/plain', \`${replacementText}\`); target.dispatchEvent( new ClipboardEvent('paste', { clipboardData: dataTransfer, // need these for the event to reach Draft paste handler bubbles: true, cancelable: true }) ); // clear DataTransfer Data dataTransfer.clearData(); } dispatchPaste(document.querySelectorAll('${richTextEditorSelector}')[0]); `; console.log(`replacementText= ${pasteReplacementText}`); // leaving this here because it may help others troubleshoot await page.evaluate(pasteReplacementText);Esa cadena compleja engaña al editor haciéndole creer que se ha pegado. Usted proporciona los datos.
Estas son algunas de las fuentes que usé para llegar a esto: