I am using Python to automate interactions with a web application. My goal is to send newline characters into an input field to separate domain names, but all attempts have failed to properly input newlines. Instead, trying different methods has either resulted in no action or has deleted the existing input.
Environment:
Here is a snippet of the function I am using to send text to an input field:
# Find the specific div element and fill it with domain names
editable_div = await tab.select('div[contenteditable="true"][role="textbox"]')
if (editable_div):
await editable_div.click() # Focus on the div
for domain in domains:
await editable_div.send_keys(domain)
await editable_div.send_keys("\n") # Send newline character
I have tried sending "\n", "\r\n", and even just "\r", but none have resulted in a newline:
Symptoms:
How can I correctly send newline characters to an input field in a web application using Python and the Nodriver library?
The input field accepts the newline when manually pressing enter key.
semrush.com/batch
It seems send_keys()
in nodriver
has problem with this page but send_keys()
in undetected_chromedriver
(created by the same author) works correctly.
But it works when I use JavaScript
to send KeyboardEvent
with keyCode: 13
and with bubbles: true
js_function = "(item) => { item.dispatchEvent(new KeyboardEvent('keydown', {keyCode: 13, bubbles: true})); }"
await editable_div.apply(js_function)
and maybe the whole point is in bubble
because this element on page is not standard textbox
but <div>
with nested <span>
for every domain - and maybe it has to send this event to parent element which catches it and it replaces Enter
with new <span>
(with next domain) inside <div>
Full working code
import asyncio
import nodriver as uc
async def main():
domains = ['A.com', 'B.com', 'C.com']
browser = await uc.start()
page = await browser.get('https://www.semrush.com/batch/')
await page.maximize()
await asyncio.sleep(5)
editable_div = await page.select('div[contenteditable="true"][role="textbox"]')
if (editable_div):
await editable_div.click()
# js_function = """() => { document.querySelector('div[role="textbox"]').dispatchEvent(new KeyboardEvent('keydown', {key: 'Enter', code: 'Enter', which: 13, keyCode: 13, bubbles: true, cancelable: true})); }"""
js_function = "(item) => { item.dispatchEvent(new KeyboardEvent('keydown', {keyCode: 13, bubbles: true})); }"
for domain in domains:
await editable_div.send_keys(domain)
#await editable_div.send_keys('\n')
#from selenium.webdriver.common.keys import Keys
#await editable_div.send_keys(Keys.ENTER)
await editable_div.apply(js_function)
if __name__ == '__main__':
uc.loop().run_until_complete(main())
input("Press ENTER to close")