0

I want to automate Gmail with selenium and python, everything works fine, but the problem here is with file attachments. How could I handle that?

These steps need to be solved:

  1. click on the file attachment button in the email compose the body.
  2. select from the local files to upload

This is my current code:

 driver.get('https://mail.google.com/mail/u/0/#inbox')
driver.implicitly_wait(15)

loginBox = driver.find_element_by_xpath('//*[@id ="identifierId"]')
loginBox.send_keys('email')

nextButton = driver.find_elements_by_xpath('//*[@id ="identifierNext"]')
nextButton[0].click()

passWordBox = driver.find_element_by_xpath('//*[@id ="password"]/div[1]/div / div[1]/input')
passWordBox.send_keys('password')

nextButton = driver.find_elements_by_xpath('//*[@id ="passwordNext"]')
nextButton[0].click()
time.sleep(2)                                 
time.sleep(2)
         
                                    #      //*[@id=":df"]/div/div   //*[@id=":df"]/div/div
  
try:

    driver.find_element_by_xpath('//div[contains(text(),"Compose")]').click()
    driver.find_element_by_xpath('//textarea[contains(@name,"to")]').send_keys('abubakkerhashmi123@gmail.com')
    driver.find_element_by_xpath('//input[contains(@name,"subjectbox")]').send_keys('Test Mail')

    bodyElem = driver.find_element_by_css_selector("div[aria-label='Message Body']") #this is where I get stuck and not sure what to do here
    bodyElem.send_keys('A test email withh selenium frm try')

   
    driver.get('https://mail.google.com/mail/u/0/#sent')
    
    # attach_file=driver.find_elements_by_id(':qn')
    # attach_file.click()
    print('choose file')
    fileInputElement = driver.find_element_by_css_selector('input[type="file"]')
    driver.execute_script("((el) => el.style.display = 'block', fileInputElement)")
    fileInputElement.send_keys('C:\\Users\\TCV\\Desktop\\abc')

    print('do you me want to send try ?')
    a=input('?')
    if 'yes' in a :
        sendElem = driver.find_element_by_xpath("//div[text()='Send']")
        sendElem.click()
  • Classic XY problem, You don't have to use selenium here, it makes everything complicated for no reason at all. Look at https://stackoverflow.com/questions/6270782/how-to-send-an-email-with-python and https://support.google.com/a/answer/176600?hl=en#zippy=%2Cuse-the-gmail-smtp-server – Anunay May 08 '21 at 15:53

1 Answers1

0

The way that selenium handles file uploads is a little hacky. WebDriver can only interact with your browser, not the window that comes up to search your filesystem for attachments. However, there is a method provided to do this if you really need to. You do this simply by identifying the file input element, and use fileInputElement.send_keys('abs/path/to/the/file/you/want/to/attach')

It's a little tricky identifying that element. But it can be identified with the CSS selector ('input[type="file"]'). Upon locating that element, we find that it is disabled. However, we can execute some Javascript to fix this. So you end up with something like

fileInputElement = driver.find_element_by_css_selector('input[type="file"]')
driver.execute_script("((el) => el.style.display = 'block', fileInputElement)")
fileInputElement.send_keys('abs/path/to/attachment/file')

Try adding a wait for visible function after the execute script to make sure it's not a timing issue.

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

fileInputElement = driver.find_element_by_css_selector('input[type="file"]')
driver.execute_script("((el) => el.style.display = 'block', fileInputElement)")
element = WebDriverWait(driver, 10).until(
        EC.visibility_of(fileInputElement)
    )
element.send_keys('abs/path/to/attachment/file')
C. Peck
  • 3,641
  • 3
  • 19
  • 36