Search code examples
pythonautomationrobotframeworkgmail-imapimaplib

Is there a way to get current imaplibrary instance from robot framework and pass to a separate python function?


i am stuck in a testcase where i need to check that after performing an action, email is getting triggered, if yes then email has an attachment.

for the first action i am using Wait For Email keyword of robotframework's imaplibrary library. now for the attachment part since there is no keyword for this purpose i have written a separate python function to which i am passing email_index as parameter written by Wait For Email keyword. after that it should walk through the email and fetch attachment.

**robot file:**

${new_email}=    Wait For Email    sender=${sender_email}   text=${expected_content}   recipient=${recepient}   timeout=70
${file}   get_attachments   ${new_email}


**python function**

import imaplib
import email

# m is the email index passed from wait for email keyword
def get_attachments(m):
    if m.get_content_maintype() == 'multipart': #multipart messages only #getting below mentioned error in this line
        for part in m.walk():

        #find the attachment part
            print part.get_content_maintype()
            if part.get_content_maintype() == 'multipart': continue
            if part.get('Content-Disposition') is None: continue

        #save the attachment in the program directory
            filename = part.get_filename()
            return filename

now the problem is i am unable to share or pass the imaplibrary session created by robot framework to a custom python function. so am getting below error.

AttributeError: 'str' object has no attribute 'get_content_maintype'

i know there is a keyword get_library_instance() in Builtin library and am already using below code for getting selenium2libray driver instance.

def get_webdriver_instance():
        se2lib = BuiltIn().get_library_instance('Selenium2Library')
        return se2lib._current_browser()

is there any similar way to solve this issue for imaplibrary ? if not please suggest a way put for it.


Solution

  • i was not able to use the instance of imaplibrary for this purpose but found another way for achieving this. the main purpose for this question is to see how to handle gmail attachments related cases in robot framework(like check/read/downloading the attachments). below is code for it. for this below is a small custom function for achieving the same.

    **robot file:**
    Check Mail
        ${new_email}=    Wait For Email    sender=${sender_email}   text=${expected_content}   recipient=${recepient}   timeout=70
        ${file}          get_attachments   ${new_email}
        log many         ${file}   
    
    
    **python function**
    
    #index is the email index passed from wait for email keyword
    def get_attachments(index):
        files=[]
        mail = imaplib.IMAP4_SSL('imap.gmail.com')
        mail.login('email', 'password')
        mail.select('inbox')
    
        result, data = mail.uid('fetch',index, '(RFC822)')
        m = email.message_from_string(data[0][1])
        if m.get_content_maintype() == 'multipart': 
            for part in m.walk():
                #logger.console(part)
    
            #find the attachment part
                if part.get_content_maintype() == 'multipart': continue
                if part.get('Content-Disposition') is None: continue
    
            #save the attachment in the program directory
                filename = part.get_filename()
                files.append(filename)
                fp = open(filename, 'wb')
                fp.write(part.get_payload(decode=True))
                fp.close()
            return files