Problem searching elements into a email list

Hi all,

I’m stuck with a script with which I intend to search for a specific email in a list of emails. For this I have a specific ‘To’ (miguelpruebatest@yopmail.com) that I want to find and a subject (Configura tu contraseña para).
If both checks match I will open that email. See an attached image of the website (mailhog) below:

The code behing this is:

In this code each line with:

is an email from the list of three.

How could i get all the 3 emails, search one by one for the one of them that match both conditions ‘To’ + Subject?

I tried with several scripts but most of them usin Get WebElements but one i get the web element it came as a Selenium Object and i don’t know how to search inside this webelement for the ‘To’ or ‘Subject’ xpath to find the text and check it. If i try to Get Text for the whole Get Element i got al the text and i think this could be improved.

Below you can find one of my attemps :
*** Settings ***
Library SeleniumLibrary
Test Teardown Cerrar Browser
Resource …/…/Resources/Webtest.resource
Suite Teardown Cerrar Browser

  *** Variables ***
  ${MAILHOG_URL}  https://xxxx.com/#  # Cambia la URL si tu Mailhog está en otro puerto

  *** Test Cases ***
  Seleccionar Email Por Para Y Asunto
      [Documentation]  Este test selecciona un email específico basado en el 'para' y el 'asunto'
      Open Browser    ${MAILHOG_URL}    ${BROWSER}    options=${BROWSER_OPTIONS}
      Maximize Browser Window
      Wait Until Page Contains Element  //div[@class="msglist-message row ng-scope"]  10s
      
      ${emails}  Get WebElements  //div[@class="msglist-message row ng-scope"]
      FOR  ${email}  IN  @{emails}
         ${To}  Get Text  ${email}//div[@ng-repeat="to in message.Content.Headers['To']"]
         Run Keyword If  '${To}' == 'miguelpruebatest@yopmail.com'  Check Email Subject  ${email}
      END


  *** Keywords ***
  Check Email Subject
      [Arguments]  ${email}
      ${subject}  Get Text  ${email}//span[@class="subject unread ng-binding"]
      Run Keyword If  '${subject}' == 'Configura tu contraseña para'  Click Element  ${email}

But as you can see i got an error :
[ FAIL ] Element with locator '<selenium.webdriver.remote.webelement.WebElement (session="5cfa3b73e2147de07b12e868e0877e19", element="f.1D31626DCBCD399E95112D1F9E69F437.d.7BC609D0014E8EDADD9B9F8531E32AC9.e.192")>//div[@ng-repeat="to in message.Content.Headers['To']"]' not found cause i don’t know how to interact with the webElement to get the info inside it.

Hi,

Depending of the DOM structure, and precision of your email sender and subject, a solution would be to search directly for the xpath containing both information (as they are somehow “linked” in strutcure and position).
Below is a example, with 3 differents locators that you could adjust (you could even add the read/unread info):

Search Mail
    [Arguments]    ${email}    ${subject}
    # Locator1 with fixed email and subject
    VAR    ${EMAIL_LOCATOR1}    //div[text()="${email}"]/following::div//span[text()="${subject}"]
    
    # Locator2 with fixed email and subject, more precise //span based on class
    VAR    ${EMAIL_LOCATOR2}    //div[text()="${email}"]/following::div//span[contains(@class, 'subject') and text()="${subject}"]
    
    # Locator3 with fixed email more precise //span based on class, partial subject
    VAR    ${EMAIL_LOCATOR3}    //div[text()="${email}"]/following::div//span[contains(@class, 'subject') and contains(text(), "${subject}")]

    ${isMail}    Run Keyword And Return Status    Element Should Be Visible    ${EMAIL_LOCATOR3}
    IF    ${isMail}
        RETURN    ${EMAIL_LOCATOR3}
    ELSE
        Log    The expected mail is not available    WARN
    END 

The idea with WebElements is a good one, but this mean having loops that may take time, moreover if your email box is not cleared.
I had some solutions like this in the past to find lines in table/tbody, but finally went to a more straightforward solution that has better performances.

Regards
Charlie

Hi Pablo,

To start with the html in this app is aweful and is not making your life easy, especially with the

  • having the ng-if email’s address above it’s div in the parent div
  • and the ng-repeat email’s div being inside the ng-if email’s div

If you have access to the dev’s give them a hard time over it. Really that should be 2 defects on the html generatiion

The way I’d approach this is to break it down to parts. first I’d create some partial xpaths variables like this:

VAR    ${expected_email}    miguelpruebatest@yopmail.com
VAR    ${expected_subject}    Configura tu contraseña para

VAR    ${xp_basemsg}    //div[contains(@class, 'msglist-message')]
VAR    ${xp_ngif}    div[contains(@class, 'ng-binding')]
VAR    ${xp_ngrepeat}    div//div[contains(@class, 'ng-binding')]
VAR    ${xp_subject}    div/span[contains(@class, 'subject')]

Next use Get Element Count to get a count of messages that match ${xp_basemsg}

Then use a FOR-IN-RANGE loop to iterate over the messages and get the email addresses and subject

once you have them you can either append them to a list, add them to a dictionary or use an if statement to take action immediately, depends what you want, but I’ll show the if statement in this example:

${msgcount}=    Get Element Count    ${xp_basemsg}
FOR    ${index}    IN RANGE    ${msgcount}
    ${To_ngif}=    Get Text    (${xp_basemsg})[${index}]/${xp_ngif}
    ${To_ngrepeat}=    Get Text    (${xp_basemsg})[${index}]/${xp_ngrepeat}
    ${subject}=    Get Text    (${xp_basemsg})[${index}]/${xp_subject}
    IF    '${To_ngif}' == '${expected_email}' and '${subject}' == '${expected_subject}'
        # matched ngif email and subject
        # do somethng
        BREAK  # exit FOR loop 
    END
    IF    '${To_ngrepeat}' == '${expected_email}' and '${subject}' == '${expected_subject}'
        # matched ngrepeat email and subject
        # do somethng
        BREAK  # exit FOR loop 
    END
END

Hopefully that’s helpful,

Dave.

@coopernico46 According to this yopmail supports the IMAP protocol Access your Yopmail.com Account with IMAP, SMTP or POP3 - August 2024. So I would use an IMAP library for Robot Framework. For example robotframework-imaplibrary2 · PyPI

Hi Lukas,

The webmail client he’s trying to script is not from yopmail, I looked at that first, so perhaps he’s tasked with testing the email web-app and has just used yopmail to send emails to it?

Dave.

Ah I see, @coopernico46 is using MailHog. Still MailHog has a JSON API that you can use instead of the web UI.

Hi @damies13 , @CharlieScene , @falcon030
Thank you all for your support.
I finally realized that the email web app allows searching, so I decided to search the email first so that all the results in the table were all from the same ‘To’ and then just search the subject.

Anyway @CharlieScene’s approach helped me learn some tricks with xpath… @damies13’s approach is possibly the one I’ll end up adopting.

Many thanks to all of you