I’m creating a framework using .NET core 2.1. I used MailKit and tried several methods as explained in their pages and also in StackOverflow but still no luck.
So far, I was able to get the UIDs of the recent messages but can’t seem to iterate through the list to get the email with the specific subject.
Test calling the method:
Core core = new Core(driver);
bool isEmailPresent = core.EnsureUnreadEmailExists("Your application details" , "emailAddress");
Assert.True(isEmailPresent);
Core (Class):
public bool EnsureUnreadEmailExists(string emailSubject, string emailBox)
{
bool emailExists = true;
//start stopwatch to monitor elapsed time
Stopwatch sw = Stopwatch.StartNew();
//long maximumTimeout = 180000; //exit loop when maximumTimeout is reached
long maximumTimeout = 10000; //exit loop when maximumTimeout is reached
int sleepWait = 500;
//check if email exists and is readable
while (CheckEmailExistsAndIsReadable(GetGmailMessage(emailBox), emailSubject) && sw.ElapsedMilliseconds <= maximumTimeout)
{
//loop until email has arrived and is activated or maximumTimeout exceeded
Thread.Sleep(sleepWait);
Console.WriteLine("Time elapsed : {0}ms", sw.ElapsedMilliseconds);
}
try
{
//try
emailExists = false;
}
catch (Exception ae)
{
//exception message
emailExists = false;
}
sw.Stop();
return emailExists;
}
private IList<UniqueId> GetGmailMessage(string emailBox)
{
// Switch on the string - emailBox.
switch (emailBox.ToUpper())
{
case "emailAddress1":
GMailHandler gmh1 = new GMailHandler("imap.gmail.com", 993, true,
"emailAddress", "password");
return gmh1.GetRecentEmails();
default:
throw new Exception("Mail box not defined");
}
}
GMailHandler (Class)
public GMailHandler(string mailServer, int port, bool ssl, string login, string password)
{
if (ssl)
Client.Connect(mailServer, port);
else
Client.Connect(mailServer, port);
Client.Authenticate(login, password);
Client.Inbox.Open(FolderAccess.ReadOnly);
}
public IList<UniqueId> GetRecentEmails()
{
IList<UniqueId> uids = client.Inbox.Search(SearchQuery.Recent);
return uids;
}
Method (in Core class) I'm unable to complete to iterate through UIDs to get email with the given subject
public static bool CheckEmailExistsAndIsReadable(IList<UniqueId> uids, string emailSubject)
{
try
{
Console.WriteLine("Attempt to read email messages .....");
string htmlBody = "";
string Subject = "";
bool EmailExists = false;
foreach (UniqueId msgId in uids)
{
//Incomplete
if (msgId.)
{
htmlBody = email.BodyHtml.Text;
Subject = email.Subject.ToString();
Console.WriteLine("Subject: " + Subject);
Match match = Regex.Match(Subject, emailSubject);
Console.WriteLine("match: " + match.Groups[0].Value.ToString());
if (match.Success)
{
Console.WriteLine("Email exists with subject line: " + emailSubject);
EmailExists = true;
}
break;
}
}
if (EmailExists)
{
//email found so exit poll
Console.WriteLine("email found return false ");
return false;
}
else
{
//email not found so contiue to poll
Console.WriteLine("email not found return true ");
return true;
}
}
catch (IOException)
{
//the email with specific subject line has not yet arrived:
//may be still in transit
//or being processed by another thread
//or does not exist (has already been processed)
Console.WriteLine("Email has not arrived or still in transit. Continue to poll ... ");
return true;
}
}
What I want to do is to add a class or two and have reusable methods, so that I can use these in any of my future tests. 1. Access gmail and validate email with a certain subject is present 2. Extract certain content (e.g. security pin) from that email and add it into a text file. 3. Check content of the email
You can try something like
public GMailHandler(string mailServer, int port, bool ssl, string login, string password)
{
if (ssl)
{
client.Connect(mailServer, port);
}
else
client.Connect(mailServer, port);
client.Authenticate(login, password);
inbox = client.Inbox;
}
public IEnumerable<string> GetEmailWithSubject (string emailSubject)
{
var messages = new List<string>();
inbox.Open(FolderAccess.ReadWrite);
var results = inbox.Search(SearchOptions.All, SearchQuery.Not(SearchQuery.Seen));
foreach (var uniqueId in results.UniqueIds)
{
var message = client.Inbox.GetMessage(uniqueId);
if (message.Subject.Contains(emailSubject))
{
messages.Add(message.HtmlBody);
}
//Mark message as read
inbox.AddFlags(uniqueId, MessageFlags.Seen, true);
}
client.Disconnect(true);
return messages;
}