Selenium with Python: Newline with Shift+Enter works but messes up the text

Viewed 465

I'm trying to automate sending messages and hence I need to go to a newline and I do it by using Shift+Enter like answered in this thread.

This is my code:

string = f"Lorem ipsum dolor sit amet\nconsectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.\n\nPS: Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus."
action = ActionChains(browser)
for part in string.split('\n'):
            action.send_keys(part)
            action.key_down(Keys.SHIFT).key_down(Keys.ENTER).key_up(Keys.ENTER).key_up(Keys.SHIFT).perform()

The output I should get is:

Lorem ipsum dolor sit amet
consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.

PS: Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.

But the output I get is more like:

Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet consectetuer adipiscing elit. Aenean commodo ligula eget Lorem ipsum dolor sit amet consectetuer adipiscing elit. Lorem ipsum dolor sit amet consectetuer adipiscing elit. Lorem ipsum dolor sit amet consectetuer adipiscing elit. Lorem ipsum dolor sit amet consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.  PS: Cum sociis natoque penatibus et magnis dis parturient montes, Lorem ipsum dolor sit amet consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.  PS: Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. nascetur ridiculus mus.
Aenean commodo ligula eget dolor. Aenean massa.  
Aenean commodo ligula eget dolor. Aenean massa. 
Aenean commodo ligula eget dolor. Aenean massa. 
dolor. Aenean massa.

Any thoughts? Thanks in advance!!

EDIT: For more context, I want to write in messenger.com, hence I can't just do Keys.ENTER, I have to do SHIFT + ENTER

4 Answers

you have to reset the actions to remove the actions in memory else it will repeat the previous actions also when you perform it:

if you are using selenium v3:

THere are two solutions:

First one:

Move action declaration inside the for loop:

for part in string.split('\n'):
    action = webdriver.ActionChains(driver)
    action.send_keys(part)
    action.key_down(Keys.SHIFT).key_down(Keys.ENTER).key_up(
        Keys.ENTER).key_up(Keys.SHIFT).perform()

This will reset the action sequence

Second appraoch:

there is reset_actions() method in action chain for this purpose , but there is abug:

https://github.com/SeleniumHQ/selenium/issues/6837

so use below approach:

for part in string.split('\n'):
    print(part)
    action.send_keys(part)
    action.key_down(Keys.SHIFT).key_down(Keys.ENTER).key_up(
        Keys.ENTER).key_up(Keys.SHIFT).perform()
    action.w3c_actions.clear_actions()
    for device in action.w3c_actions.devices:
      device.clear_actions()

If you are using selenium v4:

The bug is fixed :

to install selenium v4: pip install selenium==4.0.0.a7

for part in string.split('\n'):
    action.send_keys(part)
    action.key_down(Keys.SHIFT).key_down(Keys.ENTER).key_up(
        Keys.ENTER).key_up(Keys.SHIFT).perform()
   action.reset_actions()

please let me now if it work for you

the string is splitted by newline operator so you have to enhance it with an extra linebreak..

from selenium import webdriver
from selenium.webdriver.common.keys import Keys

driver = webdriver.Chrome('/home/stefan/Downloads/chromedriver')
driver.get("https://pastebin.com/")
text_area = driver.find_element_by_id("postform-text")

string = "Lorem ipsum dolor sit amet\nconsectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.\n\nPS: Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus."
#action = ActionChains(browser)
for part in string.split('\n'):
        print(part)
        text_area.send_keys(part)
        text_area.send_keys(Keys.ENTER)
                      
#action.key_down(Keys.SHIFT).key_down(Keys.ENTER).key_up(Keys.ENTER).key_up(Keys.SHIFT).perform()
            
driver.close()

the output i got is: enter image description here

update - send as a single msg

if you want to send it as a single message, then you dont have to split it

from selenium import webdriver
from selenium.webdriver.common.keys import Keys

driver = webdriver.Chrome('/home/stefan/Downloads/chromedriver')
driver.get("https://pastebin.com/")
text_area = driver.find_element_by_id("postform-text")

string = "Lorem ipsum dolor sit amet\nconsectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.\n\nPS: Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus."

# send as single message
text_area.send_keys(part)
text_area.send_keys(Keys.ENTER)
 
driver.close()

update 2 - specially for messengers

if i am right you want to push multiple keys to get a new line in your messenger, so you can try text_area.send_keys(Keys.SHIFT + Keys.ENTER).perform();

for part in string.split('\n'):
        text_area.send_keys(part)
        text_area.send_keys(Keys.SHIFT + Keys.ENTER).perform();

In the meantime, I have done it in a horrible and nonscalable way, but it does the job for now.

Here's the code:

one = 'Lorem ipsum dolor sit amet'
two = 'Consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.'
last = 'PS: Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.'

action = ActionChains(browser)
def newline():
    action.key_down(Keys.SHIFT).key_down(Keys.ENTER).key_up(Keys.ENTER).key_up(Keys.SHIFT)

action.send_keys(one)
newline()
action.send_keys(two)
newline()
newline()
action.send_keys(last)
action.perform()

I won't accept this answer, since it's pretty bad, so if anyone would like to give a better and cleaner answer, is fully welcome.

You can directly send strings using webelements. First you need to find the element where you want to pass the strings and you directly send strings to it.

Ex:

string='strings to be added'
element=browser.find_element_by_xpath("xpath of the element")
element.send_keys(string)
Related