/*
* 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;
import java.util.Calendar;
import java.util.Collections;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import org.testng.Assert;
import org.testng.TestException;
import com.android.ddmlib.IDevice;
import com.jayway.android.robotium.remotecontrol.solo.Solo;
import com.robin.capture.Email;
import com.robin.device.DevicePool;
import com.robin.reporter.Reporter;
import com.robin.testcase.BaseTest;
import com.robin.testcase.TestCaseSetup;
import com.robin.uielements.Locator;
import com.robin.uielements.TranslationFile;
import com.robin.uielements.TranslationMap;
import com.robin.utilities.Utilities;
import com.robin.utilities.android.IntentReceiver;
import com.robin.utilities.config.Configuration;
import com.robin.utilities.config.RobinConfiguration;
import com.robin.utilities.email.EMail;
/**
* Store common states and behaviours for BaseTest and BasePage.
* */
public class BaseFunctionality
{
/**
* Default device list wait.
*/
protected static final int DEVICE_LIST_TIMEOUT = 30000;
/**
* Default device list polling time.
*/
protected static final int DEVICE_LIST_POLLING_TIME = 1000;
private static Configuration config = new RobinConfiguration();
private static Utilities utils = new Utilities();
/**
* Stores thread specific testBase objects.
*/
private static Map<Long, TestCaseSetup> testSetups = Collections
.synchronizedMap(new HashMap<Long, TestCaseSetup>());
/**
* Basic test case related functionalities.
*/
private static RobinBaseTest test = new RobinBaseTest();
/**
* Basic reporting related functionalities.
*/
private static RobinBaseReporting log = new RobinBaseReporting();
// DEFAULT TIMEOUTS
protected final int defaultActivityTimeOut = 90000;
protected final int defaultElementTimeOut = 60000;
protected final int defaultEMailTimeOut = 60000;
protected final int defaultPollingInterval = 300;
/**
* Basic solo related functionalities.
*/
private RobinBaseFunctions core;
/**
* Basic action functionalities.
*/
private RobinBaseActions actions;
/**
* Basic checking functionalities.
*/
private RobinBaseChecks checks;
public static Configuration config()
{
return config;
}
public static Utilities utils()
{
return utils;
}
public class RobinBaseActions
{
public void rotateToLandscape(final int... indexOfSolo)
{
rotateOrientation(Solo.LANDSCAPE, indexOfSolo);
}
public void rotateToPortrait(final int... indexOfSolo)
{
rotateOrientation(Solo.PORTRAIT, indexOfSolo);
}
private void rotateOrientation(final int orientation,
final int... indexOfSolo)
{
log().line(
"Rotating orientation to "
+ log().valueStyleString(
orientation == Solo.LANDSCAPE ? "landscape"
: "portrait") + ".",
Reporter.FLASH_EVENT_STYLE,
indexOfSolo);
try
{
test().solo(indexOfSolo).setActivityOrientation(orientation);
} catch (Exception e)
{
throw new TestException(e);
}
}
}
public RobinBaseActions act()
{
if (actions == null)
{
actions = new RobinBaseActions();
}
return actions;
}
public class RobinBaseFunctions
{
public TranslationFile getTranslationsByName(
final String elementsFileName)
{
return TranslationMap.getTranslationsByName(elementsFileName);
}
/**
* Generate a new email address from a used address.
* @param emailAddress the used email (e.g.:test@gmail.com)
* @return newEmail new email address(test+DATE@gmail.com)
*/
public String newEmailAddress(final String emailAddress)
{
final String eventStyle = Reporter.READ_EVENT_STYLE;
String[] array = emailAddress.split("@");
String newEmail;
synchronized (this)
{
newEmail =
array[0] + "+"
+ utils().now(Calendar.MILLISECOND).getTime() + "@"
+ array[1];
}
log().lastInLine("Generating new email address... ", eventStyle);
log().lastInLine(
"The generated email address is "
+ log().valueStyleString(newEmail),
eventStyle);
return newEmail;
}
public String userInEmailAddress(final String emailAddress)
{
return emailAddress.split("\\+")[0];
}
public void setDeviceLocale(final IDevice device,
final Locale locale)
{
IntentReceiver receiver = new IntentReceiver();
String command =
"am broadcast -a jp.co.c_lis.ccl.morelocale.CHANGE_LOCALE"
+ " -e LOCALE_LANGUAGE "
+ locale.getLanguage().toLowerCase()
+ " -e LOCALE_VARIANT \"\"" + " -e LOCALE_COUNTRY "
+ locale.getCountry().toUpperCase();
String result = null;
try
{
System.out.println("Execute intent on device "
+ device.getSerialNumber() + ": " + command);
device.executeShellCommand(command, receiver);
result = receiver.getErrorMessage();
} catch (Exception e)
{
Assert.fail("Failed to change device language.", e);
e.printStackTrace();
}
Assert.assertNull(result, "Error during intent broadcast '"
+ command + "' : " + result);
Assert.assertTrue(
locale.equals(core().getDviceLocale(device)),
"Device " + device.getSerialNumber() + " did not set language "
+ locale);
}
public Locale getDviceLocale(final IDevice device)
{
return DevicePool.getDeviceLanguage(device);
}
}
public RobinBaseFunctions core()
{
if (core == null)
{
core = new RobinBaseFunctions();
}
return core;
}
public static class RobinBaseReporting
{
public void line(final String message, final String style,
final int... indexOfSolo)
{
test()
.setup()
.getReporter()
.log(sessionReportSign(indexOfSolo) + message, style);
}
public void firstInLine(final String message, final String style,
final int... indexOfSolo)
{
test()
.setup()
.getReporter()
.logInLine(sessionReportSign(indexOfSolo) + message, style);
}
public void inLine(final String message, final String style)
{
firstInLine(message, style);
}
public void lastInLine(final String message, final String style)
{
line(message, style);
}
public void tic()
{
test().setup().tic();
}
private String toc()
{
return test().setup().toc();
}
public void toc(final String style)
{
lastInLine(" " + valueStyleString(toc()) + " ms.", style);
}
/**
* Generates a string to sign solo session related reporter
* character sequence.
* @param indexOfSolo index of solo in use
* @return the string that will appear for the given report line for the
* current solo session in use returns empty string if only
* one solo session is available.
*/
private String sessionReportSign(final int... indexOfSolo)
{
if (indexOfSolo.length > 0
&& test().lastSoloIndex() > 0)
{
String sign = "";
for (int i = 0; i <= indexOfSolo[0]; i++)
{
sign = sign + ">";
}
return sign + " ";
} else
{
return "";
}
}
public String valueStyleString(final String message)
{
return Reporter.getDiv(Reporter.VALUE_STYLE, message);
}
public String locatorStyleString(final Locator locator)
{
return Reporter.getDiv(Reporter.LOCATOR_STYLE, locator.getValue());
}
public String elementStyleString(final String message)
{
return Reporter.getDiv(Reporter.ELEMENT_NAME_STYLE, message);
}
}
public RobinBaseReporting log()
{
if (log == null)
{
log = new RobinBaseReporting();
}
return log;
}
public static class RobinBaseTest
{
public String sessionReportSign(final int... indexOfSolo)
{
return log.sessionReportSign(indexOfSolo);
}
public TestCaseSetup setup()
{
synchronized (testSetups)
{
return testSetups.get(threadId());
}
}
public void addSetup(final TestCaseSetup testCaseSetup)
{
synchronized (testSetups)
{
testSetups.put(threadId(), testCaseSetup);
}
}
public String deviceDescriptionString(final int... indexOfSolo)
{
return DevicePool.getDeviceDescriptionString(setup().getDevice(
indexOfSolo));
}
public int lastSoloIndex()
{
return setup().getLastSoloIndex();
}
public String className()
{
return setup().getTestClassName();
}
public String methodName()
{
return setup().getMethodName();
}
public String screenShotFileName(final int... indexOfSolo)
{
return fileName(indexOfSolo) + ".png";
}
public String fileName(final int... indexOfSolo)
{
return className() + "_" + methodName() + "_"
+ deviceDescriptionString(indexOfSolo) + "_"
+ utils().getTimeStamp();
}
public Solo solo(final int... indexOfSolo)
{
return setup().getSolo(indexOfSolo);
}
public long threadId()
{
return Thread.currentThread().getId();
}
public int verbLevel()
{
return setup().getReporter().getVerbLevel();
}
public void decreaseVerbosity()
{
setup().getReporter().decreaseVerbosity();
}
public void increaseVerbosity()
{
setup().getReporter().increaseVerbosity();
}
}
public static RobinBaseTest test()
{
if (test == null)
{
test = new RobinBaseTest();
}
return test;
}
public class RobinBaseChecks
{
public void activityLoaded(final String acitivyName,
final int... indexOfSolo)
{
final String eventStyle = Reporter.WAIT_EVENT_STYLE;
log().firstInLine(
"Waiting for the activity "
+ log()
.elementStyleString(acitivyName)
+ " to appear... ",
eventStyle);
log().tic();
boolean success = false;
try
{
success = test().solo(indexOfSolo).waitForActivity(
acitivyName,
defaultElementTimeOut);
} catch (Exception e)
{
throw new TestException(e);
}
String currentActivity = "";
if (!success)
{
try
{
currentActivity =
test().solo(indexOfSolo).getCurrentActivity();
} catch (Exception e)
{
e.printStackTrace();
} finally
{
Assert.assertTrue(success, "The '" + acitivyName
+ "' activity did not become active within "
+ defaultElementTimeOut + "ms. Current activity is '"
+ currentActivity + "'.");
}
}
log().toc(eventStyle);
}
public void activityLoaded(
@SuppressWarnings("rawtypes") final Class activityClass,
final int... indexOfSolo)
{
final String activityName = activityClass.getSimpleName();
activityLoaded(activityName, indexOfSolo);
}
public EMail newMail(final String username, final String password)
{
final String readEventStyle = Reporter.READ_EVENT_STYLE;
log().inLine(
"Waiting for new mail to arrive at "
+ log().valueStyleString(username) + "@gmail.com ...",
readEventStyle);
log().tic();
EMail mail =
utils().waitForMailSubjectContains(
username,
password,
"",
defaultEMailTimeOut);
log().toc(readEventStyle);
final String fileName =
BaseTest.test().screenShotFileName().replace(".png", ".html");
Email.capture(fileName, mail);
return mail;
}
public EMail newMailSubjectContains(final String username,
final String password, final String subject)
{
final String eventStyle = Reporter.READ_EVENT_STYLE;
log().inLine(
"Waiting for new mail with " + log().valueStyleString(subject)
+ " contained subject to arrrive at "
+ log().valueStyleString(username) + "@gmail.com ...",
eventStyle);
log().tic();
EMail mail =
utils().waitForMailSubjectContains(
username,
password,
subject,
defaultEMailTimeOut);
log().toc(eventStyle);
final String fileName =
BaseTest.test().screenShotFileName().replace(".png", ".html");
Email.capture(fileName, mail);
return mail;
}
public EMail
newMailToAndSubjectContains(final String username,
final String password, final String recepient,
final String subject)
{
final String eventStyle = Reporter.READ_EVENT_STYLE;
log().inLine(
"Waiting for new mail with " + log().valueStyleString(subject)
+ " contained subject addressed for "
+ log().valueStyleString(recepient) + " to arrive ...",
eventStyle);
log().tic();
EMail mail =
utils().waitForMailToAndSubjectContains(
username,
password,
recepient,
subject,
defaultEMailTimeOut);
log().toc(eventStyle);
final String fileName =
BaseTest.test().screenShotFileName().replace(".png", ".html");
Email.capture(fileName, mail);
return mail;
}
public void newEmailBodyToAndSubjectContains(final String userName,
final String password, final String recepient,
final String subject, final String... elements)
{
boolean checkContains = true;
EMail email =
newMailToAndSubjectContains(
userName,
password,
recepient,
subject);
String bodyText = email.getBodyText();
for (int i = 0; i < elements.length; i++)
{
checkContains = bodyText.contains(elements[i]);
if (checkContains)
{
log().line(
"Checking the email body contains the "
+ log().valueStyleString(elements[i])
+ " element.",
Reporter.CHECKING_EVENT_STYLE);
} else
{
Assert.fail("The email body doesn't contain the '"
+ elements[i] + "' element.");
}
}
}
}
public RobinBaseChecks check()
{
if (checks == null)
{
checks = new RobinBaseChecks();
}
return checks;
}
}