/*
* Copyright (C) 2013 Ustream Inc.
* author chaotx <lombai.ferenc@ustream.tv>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
package com.robin.utilities;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.Properties;
import java.util.Random;
import java.util.TimeZone;
import java.util.concurrent.TimeUnit;
import javax.mail.Flags;
import javax.mail.Flags.Flag;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.internet.MimeMessage.RecipientType;
import javax.mail.search.AndTerm;
import javax.mail.search.FlagTerm;
import javax.mail.search.RecipientStringTerm;
import javax.mail.search.SearchTerm;
import javax.mail.search.SubjectTerm;
import org.apache.commons.lang.time.DateUtils;
import org.openqa.selenium.support.ui.FluentWait;
import org.testng.Assert;
import com.google.common.base.Function;
import com.robin.reporter.Reporter;
import com.robin.utilities.email.EMail;
public final class Utilities
{
/**
* A utility that waits for a gmail mailbox to receive a new message which
* subject contains a specific string.
* @param username the mailbox owner's user name (no @gmail.com required).
* @param pass the user password protecting this mailbox
* @param subject the string that must be contained in the new mail
* @param timeout The maximum amount of time to wait in milliseconds.
* @return a last from the new messages thats subject contains the specified
* string
*/
public EMail waitForMailSubjectContains(final String username,
final String pass, final String subject, final long timeout)
{
SearchTerm st = new SubjectTerm(subject);
return waitForMailWithSearchTerm(
username,
pass,
st,
"No new mail arrived to " + username
+ "@gmail.com with subject containing '" + subject + "'.",
timeout);
}
/**
* A utility that waits for a gmail mailbox to receive a new message which
* subject contains a specific string and the TO recipient is also given.
* @param username the mailbox owner's user name (no @gmail.com required).
* @param pass the user password protecting this mailbox
* @param recepient the recipient given as a TO type
* @param subject the string that must be contained in the new mail
* @param timeout The maximum amount of time to wait in milliseconds.
* @return a last from the new messages thats subject contains the specified
* string
*/
public EMail waitForMailToAndSubjectContains(final String username,
final String pass, final String recepient, final String subject,
final long timeout)
{
SearchTerm st =
new AndTerm(
new RecipientStringTerm(RecipientType.TO, recepient),
new SubjectTerm(subject));
return waitForMailWithSearchTerm(
username,
pass,
st,
"No new mail arrived to '" + recepient
+ "' with subject containing '" + subject + "'.",
timeout);
}
/**
* A utility that waits for a gmail mailbox to receive a new message with
* according to a given SearchTerm. Only "Not seen" messages are searched,
* and all match is set as SEEN, but just the first occurrence of the
* matching message is returned.
* @param username the mailbox owner's user name (no @gmail.com required).
* @param pass the user password protecting this mailbox
* @param st the SearchTerm built to filter messages
* @param timeoutMessage the message to show when no such mail found within
* timeout
* @param timeout The maximum amount of time to wait in milliseconds.
* @return a last from the new messages thats match the st conditions
*/
public EMail waitForMailWithSearchTerm(final String username,
final String pass, final SearchTerm st, final String timeoutMessage,
final long timeout)
{
String host = "imap.gmail.com";
final long retryTime = 1000;
Properties props = System.getProperties();
props.setProperty("mail.store.protocol", "imaps");
props.put("mail.imaps.ssl.trust", "*");
EMail email = null;
Session session = Session.getDefaultInstance(props, null);
try
{
Store store = session.getStore("imaps");
store.connect(host, username, pass);
Folder inbox = store.getFolder("Inbox");
inbox.open(Folder.READ_WRITE);
FluentWait<Folder> waitForMail =
new FluentWait<Folder>(inbox)
.withTimeout(timeout, TimeUnit.MILLISECONDS)
.pollingEvery(retryTime, TimeUnit.MILLISECONDS)
.withMessage(timeoutMessage);
email = waitForMail.until(new Function<Folder, EMail>()
{
@Override
public EMail apply(final Folder inbox)
{
EMail email = null;
FlagTerm ft =
new FlagTerm(new Flags(Flags.Flag.SEEN), false);
SearchTerm sst = new AndTerm(ft, st);
try
{
inbox.getMessageCount();
Message[] messages = inbox.search(sst);
for (Message message : messages)
{
message.setFlag(Flag.SEEN, true);
}
if (messages.length > 0)
{
return new EMail(messages[0]);
}
} catch (MessagingException e)
{
Assert.fail(e.getMessage());
}
return email;
}
});
inbox.close(false);
store.close();
} catch (MessagingException e)
{
Assert.fail(e.getMessage());
}
return email;
}
/**
* A utility that waits for a specific amount of time.
* @param timeToWait Time to wait in ms.
*/
public static void waitTime(final long timeToWait)
{
try
{
Thread.sleep(timeToWait);
} catch (InterruptedException e)
{
Reporter.log(e.getMessage());
e.printStackTrace();
}
}
/**
* A utility that generates random String with a given length of characters.
* Duplicate entries are allowed.
* The random string contains lowercase characters and numbers.
* @param length the generated String's length
* @return the generated random String
*/
public String generateRandomString(final int length)
{
final String validCharacters =
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
final Random randomGenerator = new Random();
int randIndex = 0;
String randomString = "";
for (int i = 0; i < length; i++)
{
randIndex = randomGenerator.nextInt(validCharacters.length());
randomString =
randomString
+ validCharacters.substring(randIndex, randIndex + 1);
}
return randomString;
}
/**
* A utility that generates random String with a given length of characters.
* Duplicate entries are allowed.
* The random string contains lowercase characters and numbers.
* @param length the generated String's length
* @param notThis a string that must not be generated
* @return the generated random String
*/
public String generateRandomString(final int length, final String notThis)
{
final int maxTry = 777;
int numOfTry = 0;
String randomString = notThis;
while (notThis.startsWith(randomString) && numOfTry < maxTry)
{
randomString = generateRandomString(length);
numOfTry++;
}
if (numOfTry >= maxTry)
{
Assert.fail("Could not generate " + length
+ " length random string that differs from '" + notThis
+ "' within " + numOfTry + "trials. Go and buy a lottery!");
}
return randomString;
}
/**
* Gives the actual time date with a minute precision.
* @return The truncated date object.
*/
public Date now()
{
return now(Calendar.MINUTE);
}
/**
* Gives the actual time date with a given precision.
* @param precision the date precision (like Calendar.SECOND).
* @return The truncated date object.
*/
public Date now(final int precision)
{
return DateUtils.truncate(new Date(), precision);
}
/**
* Gives the actual time in the specified format by using SimpleDateFormat
* and Calendar.
* @param dateFormat the format string of the returned time text. (e.g.
* "yyyy-MM-dd HH:mm:ss")
* @param timeZone the time zone of the current time
* @return The current date formatted according to the given dateFormat and
* time zone.
*/
public String now(final String dateFormat, final TimeZone timeZone)
{
return dateToString(now(), dateFormat, timeZone);
}
/**
* Formats a date to string by SimpledateFormat rules in a given time zone.
* @param date the date to write to string
* @param dateFormat the format string of the returned time text. (e.g.
* "yyyy-MM-dd HH:mm:ss")
* @param timeZone the time zone of the current time
* @return The date formatted according to the given dateFormat and time
* zone.
*/
public String dateToString(final Date date, final String dateFormat,
final TimeZone timeZone)
{
SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
sdf.setTimeZone(timeZone);
return sdf.format(date);
}
/**
* Formats a date to string by SimpledateFormat rules in a given time zone
* and the locale to use.
* @param date the date to write to string
* @param dateFormat the format string of the returned time text. (e.g.
* "yyyy-MM-dd HH:mm:ss")
* @param timeZone the time zone of the current time
* @param locale The locale to use.
* @return The date formatted according to the given dateFormat and time
* zone.
*/
public String dateToString(final Date date, final String dateFormat,
final TimeZone timeZone, final Locale locale)
{
SimpleDateFormat sdf = new SimpleDateFormat(dateFormat, locale);
sdf.setTimeZone(timeZone);
return sdf.format(date);
}
/**
* Add time to a specific date.
* @param date the date to add time to
* @param calendarField The calendar field (e.g. Calendar.Day,
* Calendar.Hour) which increase the value.
* @param valueToAdd the number to Add the selected calendar field.
* @return The date object calculated
*/
public Date datePlusTime(final Date date, final int calendarField,
final int valueToAdd)
{
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.add(calendarField, valueToAdd);
return cal.getTime();
}
/**
* Add time to actual time.
* @param calendarField The calendar field (e.g. Calendar.Day,
* Calendar.Hour) which increase the value.
* @param valueToAdd the number to Add the selected calendar field.
* @return The date object according to the given added time
*/
public Date nowPlusTime(final int calendarField, final int valueToAdd)
{
return datePlusTime(now(), calendarField, valueToAdd);
}
/**
* Add time to the actual time in the specified format by using
* SimpleDateFormat and Calendar.
* @param dateFormat the format string of the returned time text. (e.g.
* "yyyy-MM-dd HH:mm:ss")
* @param calendarField The calendar field (e.g. Calendar.Day,
* Calendar.Hour) which increase the value.
* @param valueToAdd the number to Add the selected calendar field.
* @param timeZone the time zone of the current time
* @return The date formatted according to the given dateFormat
*/
public String
nowPlusTime(final String dateFormat, final int calendarField,
final int valueToAdd, final TimeZone timeZone)
{
return dateToString(
datePlusTime(now(), calendarField, valueToAdd),
dateFormat,
timeZone);
}
/**
* Gives a time stamp in the format of 'YYMMddHHmmss'.
* @return The time stamp string.
*/
public String getTimeStamp()
{
return dateToString(
now(Calendar.SECOND),
"yyMMddHHmmss",
TimeZone.getDefault());
}
public String generateOneRandomLetter()
{
final Random randomGenerator = new Random();
final String validCharacters =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
int randIndex = 0;
randIndex = randomGenerator.nextInt(validCharacters.length());
final String randomLetter =
validCharacters.substring(randIndex, randIndex + 1);
return randomLetter;
}
public String generateOneRandomAccent()
{
final Random randomGenerator = new Random();
final String validCharacters = ",?:-;'+!%=()|<>*";
int randIndex = 0;
randIndex = randomGenerator.nextInt(validCharacters.length());
final String randomAccent =
validCharacters.substring(randIndex, randIndex + 1);
return randomAccent;
}
public static void moveFileAndReplace(final File target,
final File destination)
{
if (destination.exists())
{
Assert.assertTrue(destination.delete(), "Could not delete '"
+ destination.getAbsolutePath() + "'.");
}
Assert.assertTrue(
target.renameTo(destination),
"Could not move '" + target.getAbsolutePath() + "' to '"
+ destination.getAbsolutePath() + "'.");
}
}