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
1 Like
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.
1 Like
@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.
2 Likes
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
3 Likes