merge heads

This commit is contained in:
Jimmy Shih
2012-12-20 10:05:56 -08:00
31 changed files with 1087 additions and 148 deletions
@@ -1,215 +0,0 @@
/*
* Copyright 2012 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.android.apps.mytracks.endtoendtest;
import com.google.android.apps.mytracks.TrackListActivity;
import com.google.android.maps.mytracks.R;
import android.app.Instrumentation;
import android.test.ActivityInstrumentationTestCase2;
import android.view.KeyEvent;
import android.widget.CheckBox;
import java.util.ArrayList;
/**
* Tests creating a track with markers, and editing and sending send a track.
*
* @author Youtao Liu
*/
public class CreateTrackTest extends ActivityInstrumentationTestCase2<TrackListActivity> {
private Instrumentation instrumentation;
private TrackListActivity activityMyTracks;
public CreateTrackTest() {
super(TrackListActivity.class);
}
@Override
protected void setUp() throws Exception {
super.setUp();
instrumentation = getInstrumentation();
activityMyTracks = getActivity();
EndToEndTestUtils.setupForAllTest(instrumentation, activityMyTracks);
}
/**
* Does not check any service and try to send to google.
*/
public void testCreateAndSendTrack_notSend() {
EndToEndTestUtils.createTrackIfEmpty(1, false);
instrumentation.waitForIdleSync();
EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_send_google), true);
EndToEndTestUtils.SOLO.waitForText(activityMyTracks.getString(R.string.send_google_title));
EndToEndTestUtils.rotateCurrentActivity();
instrumentation.waitForIdleSync();
ArrayList<CheckBox> checkBoxs = EndToEndTestUtils.SOLO.getCurrentCheckBoxes();
for (int i = 0; i < checkBoxs.size(); i++) {
if (checkBoxs.get(i).isChecked()) {
EndToEndTestUtils.SOLO.clickOnCheckBox(i);
}
}
if (checkBoxs.size() < 3) {
EndToEndTestUtils.SOLO.scrollDown();
checkBoxs = EndToEndTestUtils.SOLO.getCurrentCheckBoxes();
for (int i = 0; i < checkBoxs.size(); i++) {
if (checkBoxs.get(i).isChecked()) {
EndToEndTestUtils.SOLO.clickOnCheckBox(i);
}
}
}
instrumentation.waitForIdleSync();
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.send_google_send_now));
assertTrue(EndToEndTestUtils.SOLO.waitForText(activityMyTracks
.getString(R.string.send_google_no_service_selected)));
// Stop here for do not really send.
}
/**
* Tests editing a track.
*/
public void testEditTrack() {
EndToEndTestUtils.createTrackIfEmpty(1, false);
instrumentation.waitForIdleSync();
EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_edit), true);
String newTrackName = EndToEndTestUtils.TRACK_NAME_PREFIX + "_new" + System.currentTimeMillis();
String newType = EndToEndTestUtils.activityType;
String newDesc = "desc" + newTrackName;
instrumentation.waitForIdleSync();
EndToEndTestUtils.rotateAllActivities();
EndToEndTestUtils.SOLO.waitForText(activityMyTracks.getString(R.string.generic_save));
sendKeys(KeyEvent.KEYCODE_DEL);
EndToEndTestUtils.enterTextAvoidSoftKeyBoard(0, newTrackName);
EndToEndTestUtils.enterTextAvoidSoftKeyBoard(1, newType);
EndToEndTestUtils.enterTextAvoidSoftKeyBoard(2, newDesc);
EndToEndTestUtils.SOLO.clickOnButton(activityMyTracks.getString(R.string.generic_save));
instrumentation.waitForIdleSync();
// Go back to track list.
EndToEndTestUtils.SOLO.goBack();
instrumentation.waitForIdleSync();
assertTrue(EndToEndTestUtils.SOLO.searchText(newTrackName));
assertTrue(EndToEndTestUtils.SOLO.searchText(newDesc));
}
/**
* Creates one track with a two locations, a way point and a statistics point.
*/
public void testCreateTrackWithMarkers() {
EndToEndTestUtils.startRecording();
instrumentation.waitForIdleSync();
// Send Gps before send marker.
EndToEndTestUtils.sendGps(2);
if (EndToEndTestUtils.hasActionBar) {
// Check the title is Recording.
assertTrue(EndToEndTestUtils.SOLO.searchText(activityMyTracks
.getString(R.string.generic_recording)));
}
EndToEndTestUtils.createWaypoint(0);
EndToEndTestUtils.sendGps(2, 2);
// Back to tracks list.
EndToEndTestUtils.SOLO.goBack();
instrumentation.waitForIdleSync();
EndToEndTestUtils.rotateAllActivities();
EndToEndTestUtils.stopRecording(false);
EndToEndTestUtils.trackName = EndToEndTestUtils.TRACK_NAME_PREFIX + System.currentTimeMillis();
EndToEndTestUtils.SOLO.enterText(0, EndToEndTestUtils.trackName);
EndToEndTestUtils.SOLO.enterText(1, EndToEndTestUtils.activityType);
EndToEndTestUtils.SOLO.clickOnButton(activityMyTracks.getString(R.string.generic_save));
instrumentation.waitForIdleSync();
// Check the new track
EndToEndTestUtils.SOLO.scrollUp();
assertTrue(EndToEndTestUtils.SOLO.waitForText(EndToEndTestUtils.trackName, 1,
EndToEndTestUtils.NORMAL_WAIT_TIME, true, false));
}
/**
* Tests the display of track start time. Use relative time (x mins ago) for
* the start time if it is within the past week. But only show the start time
* if it is different from the track name.
*/
public void testTrackStartTime() {
// Delete all track first.
EndToEndTestUtils.deleteAllTracks();
// Reset all settings.
EndToEndTestUtils.resetAllSettings(activityMyTracks, false);
assertTrue(EndToEndTestUtils.SOLO.waitForText(activityMyTracks.getString(R.string.track_list_empty_message)));
// Test should not show relative time.
EndToEndTestUtils.startRecording();
instrumentation.waitForIdleSync();
EndToEndTestUtils.stopRecording(false);
instrumentation.waitForIdleSync();
EndToEndTestUtils.getButtonOnScreen(activityMyTracks.getString(R.string.generic_save), true,
true);
instrumentation.waitForIdleSync();
EndToEndTestUtils.SOLO.goBack();
instrumentation.waitForIdleSync();
assertFalse(EndToEndTestUtils.SOLO.searchText(EndToEndTestUtils.RELATIVE_STARTTIME_POSTFIX, 1, false, true));
// Test should show relative time for createSimpleTrack would save a track
// name that is different with the start time.
EndToEndTestUtils.createSimpleTrack(2, true);
assertTrue(EndToEndTestUtils.SOLO.waitForText(EndToEndTestUtils.RELATIVE_STARTTIME_POSTFIX, 1, EndToEndTestUtils.NORMAL_WAIT_TIME));
}
/**
* Tests whether the split marker is created as setting.
*/
public void testSplitSetting() {
EndToEndTestUtils.startRecording();
EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_split_frequency), true);
boolean isFoundKM = EndToEndTestUtils.SOLO.searchText(EndToEndTestUtils.KM);
if (isFoundKM) {
EndToEndTestUtils.SOLO.clickOnText(EndToEndTestUtils.KM, 0);
} else {
EndToEndTestUtils.SOLO.clickOnText(EndToEndTestUtils.MILE, 0);
}
EndToEndTestUtils
.getButtonOnScreen(activityMyTracks.getString(R.string.generic_ok), true, true);
// Send Gps to give a distance more than one kilometer or one mile.
EndToEndTestUtils.sendGps(20);
assertTrue(EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_markers),
true));
instrumentation.waitForIdleSync();
if (EndToEndTestUtils.hasGpsSingal) {
assertTrue(EndToEndTestUtils.SOLO.getCurrentListViews().get(0).getCount() > 0);
} else {
assertTrue(EndToEndTestUtils.SOLO.getCurrentListViews().get(0).getCount() == 0);
}
EndToEndTestUtils.SOLO.goBack();
EndToEndTestUtils.stopRecording(true);
}
@Override
protected void tearDown() throws Exception {
EndToEndTestUtils.SOLO.finishOpenedActivities();
super.tearDown();
}
}
@@ -1,123 +0,0 @@
/*
* Copyright 2012 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.android.apps.mytracks.endtoendtest;
import com.google.android.apps.mytracks.TrackListActivity;
import com.google.android.maps.mytracks.R;
import android.app.Instrumentation;
import android.test.ActivityInstrumentationTestCase2;
import android.widget.ListView;
import java.util.ArrayList;
/**
* Tests the delete of MyTracks.
*
* @author Youtao Liu
*/
public class DeleteTest extends ActivityInstrumentationTestCase2<TrackListActivity> {
private Instrumentation instrumentation;
private TrackListActivity activityMyTracks;
public DeleteTest() {
super(TrackListActivity.class);
}
@Override
protected void setUp() throws Exception {
super.setUp();
instrumentation = getInstrumentation();
activityMyTracks = getActivity();
EndToEndTestUtils.setupForAllTest(instrumentation, activityMyTracks);
}
/**
* Deletes all tracks.
*/
public void testDeleteAllTracks() {
EndToEndTestUtils.createTrackIfEmpty(1, true);
instrumentation.waitForIdleSync();
// There is at least one track.
ArrayList<ListView> trackListView = EndToEndTestUtils.SOLO.getCurrentListViews();
assertTrue(trackListView.size() > 0);
assertTrue(trackListView.get(0).getCount() > 0);
EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_delete_all), true);
instrumentation.waitForIdleSync();
EndToEndTestUtils.rotateAllActivities();
EndToEndTestUtils
.getButtonOnScreen(activityMyTracks.getString(R.string.generic_ok), true, true);
instrumentation.waitForIdleSync();
assertTrue(EndToEndTestUtils.SOLO.waitForText(activityMyTracks
.getString(R.string.track_list_empty_message)));
// There is no track now.
trackListView = EndToEndTestUtils.SOLO.getCurrentListViews();
assertEquals(0, trackListView.get(0).getCount());
// Export when there is no track.
EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_save_all), true);
EndToEndTestUtils.SOLO
.clickOnText(String.format(activityMyTracks.getString(R.string.menu_save_format),
EndToEndTestUtils.GPX.toUpperCase()));
assertTrue(EndToEndTestUtils.SOLO.waitForText(activityMyTracks
.getString(R.string.external_storage_save_error_no_track)));
EndToEndTestUtils
.getButtonOnScreen(activityMyTracks.getString(R.string.generic_ok), true, true);
}
/**
* Deletes only one track.
*/
public void testDeleteSingleTrack() {
EndToEndTestUtils.createTrackIfEmpty(1, true);
instrumentation.waitForIdleSync();
// Get the number of track( or tracks)
ArrayList<ListView> trackListView = EndToEndTestUtils.SOLO.getCurrentListViews();
int trackNumberOld = trackListView.get(0).getCount();
EndToEndTestUtils.SOLO.clickOnView(trackListView.get(0).getChildAt(0));
EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_delete), true);
EndToEndTestUtils
.getButtonOnScreen(activityMyTracks.getString(R.string.generic_ok), true, true);
instrumentation.waitForIdleSync();
trackListView = EndToEndTestUtils.SOLO.getCurrentListViews();
int trackNumberNew = trackListView.get(0).getCount();
assertEquals(trackNumberOld - 1, trackNumberNew);
}
/**
* Deletes a track which is under recording.
*/
public void testDeleteOneTrackUnderRecording() {
EndToEndTestUtils.startRecording();
instrumentation.waitForIdleSync();
EndToEndTestUtils.checkUnderRecording();
instrumentation.waitForIdleSync();
EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_delete), true);
EndToEndTestUtils
.getButtonOnScreen(activityMyTracks.getString(R.string.generic_ok), true, true);
instrumentation.waitForIdleSync();
EndToEndTestUtils.checkNotRecording();
}
@Override
protected void tearDown() throws Exception {
EndToEndTestUtils.SOLO.finishOpenedActivities();
super.tearDown();
}
}
@@ -1,68 +0,0 @@
/*
* Copyright 2012 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.android.apps.mytracks.endtoendtest;
import com.google.android.apps.mytracks.endtoendtest.others.BigTestUtils;
import android.os.Bundle;
import android.test.InstrumentationTestRunner;
import android.util.Log;
/**
* A test runner can be used to run end-to-end test.
*
* @author Youtao Liu
*/
public class EndToEndTestRunner extends InstrumentationTestRunner {
/**
* Gets the parameter port which is used to fix GPS signal to emulators.
*/
@Override
public void onCreate(Bundle arguments) {
String portNumber = arguments.getString("port");
if (portNumber != null) {
try {
EndToEndTestUtils.emulatorPort = Integer.parseInt(portNumber);
} catch (Exception e) {
Log.e(EndToEndTestUtils.LOG_TAG, "Unable to get port parameter, use default value."
+ EndToEndTestUtils.emulatorPort, e);
}
}
String isStressTest = arguments.getString("stress");
if (isStressTest != null && isStressTest.equalsIgnoreCase("true")) {
BigTestUtils.runStressTest = true;
} else {
BigTestUtils.runStressTest = false;
}
String isSensorTest = arguments.getString("sensor");
if (isSensorTest != null && isSensorTest.equalsIgnoreCase("true")) {
BigTestUtils.runSensorTest = true;
} else {
BigTestUtils.runSensorTest = false;
}
Log.d(EndToEndTestUtils.LOG_TAG, "Use port number when run test on emulator:"
+ EndToEndTestUtils.emulatorPort);
Log.i(EndToEndTestUtils.LOG_TAG, "Run stress test:" + BigTestUtils.runStressTest);
Log.i(EndToEndTestUtils.LOG_TAG, "Run sensor test:" + BigTestUtils.runSensorTest);
super.onCreate(arguments);
}
}
@@ -1,980 +0,0 @@
/*
* Copyright 2012 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.android.apps.mytracks.endtoendtest;
import com.google.android.apps.mytracks.ChartView;
import com.google.android.apps.mytracks.TrackListActivity;
import com.google.android.apps.mytracks.util.FileUtils;
import com.google.android.apps.mytracks.util.StringUtils;
import com.google.android.maps.mytracks.R;
import com.jayway.android.robotium.solo.Solo;
import android.app.Activity;
import android.app.Instrumentation;
import android.content.Context;
import android.content.res.Configuration;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.TextView;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.io.PrintStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Locale;
import junit.framework.Assert;
/**
* Provides utilities to smoke test.
*
* @author Youtao Liu
*/
public class EndToEndTestUtils {
private static final String ANDROID_LOCAL_IP = "10.0.2.2";
// usually 5554.
public static int emulatorPort = 5554;
private static final int ORIENTATION_PORTRAIT = 1;
private static final int ORIENTATION_LANDSCAPE = 0;
// Pause 200ms between each send.
private static final int PAUSE_DEFAULT = 200;
static final double START_LONGITUDE = 51;
static final double START_LATITUDE = -1.3f;
static final double DELTA_LONGITUDE = 0.0005f;
static final double DELTA_LADITUDE = 0.0005f;
private static final String WAYPOINT_NAME = "testWaypoint";
private static final String NO_GPS_MESSAGE_PREFIX = "GPS is not available";
private static final String MOREOPTION_CLASSNAME = "com.android.internal.view.menu.ActionMenuPresenter$OverflowMenuButton";
private static final String MENUITEM_CLASSNAME = "com.android.internal.view.menu.IconMenuItemView";
static final String DEFAULTACTIVITYTYPE = "TestActivity";
public static String activityType = DEFAULTACTIVITYTYPE;
static final String TRACK_NAME_PREFIX = "testTrackName";
static final String GPX = "gpx";
static final String KML = "kml";
static final String CSV = "csv";
static final String TCX = "tcx";
static final String BACKUPS = "backups";
static final String MENU_MORE = "More";
static String trackName;
// Following is some check strings in English and Chinese
private static final HashMap<String, String> RELATIVE_STARTTIME_POSTFIX_MULTILINGUAL = new HashMap<String, String>();
private static final HashMap<String, String> KM_MULTILINGUAL = new HashMap<String, String>();
private static final HashMap<String, String> MILE_MULTILINGUAL = new HashMap<String, String>();
public static String RELATIVE_STARTTIME_POSTFIX = "";
public static String KM = "";
public static String MILE = "";
public static int VERY_SHORT_WAIT_TIME = 500;
public static int SHORT_WAIT_TIME = 2000;
public static int NORMAL_WAIT_TIME = 8000;
public static int LONG_WAIT_TIME = 15000;
public static int SUPER_LONG_WAIT_TIME = 100000;
public static String deviceLanguage = "";
static {
RELATIVE_STARTTIME_POSTFIX_MULTILINGUAL.put("es", "mins ago");
RELATIVE_STARTTIME_POSTFIX_MULTILINGUAL.put("de", "Minuten");
RELATIVE_STARTTIME_POSTFIX_MULTILINGUAL.put("fr", "minute");
RELATIVE_STARTTIME_POSTFIX_MULTILINGUAL.put("ar", "دقيقة");
RELATIVE_STARTTIME_POSTFIX_MULTILINGUAL.put("zh", "分钟前");
KM_MULTILINGUAL.put("es", "km");
KM_MULTILINGUAL.put("de", "km");
KM_MULTILINGUAL.put("fr", "km");
KM_MULTILINGUAL.put("ar", "كم");
KM_MULTILINGUAL.put("zh", "公里");
MILE_MULTILINGUAL.put("es", "mi");
MILE_MULTILINGUAL.put("de", "mi");
MILE_MULTILINGUAL.put("fr", "mile");
MILE_MULTILINGUAL.put("ar", "ميل");
MILE_MULTILINGUAL.put("zh", "英里");
}
public static Solo SOLO;
public static Instrumentation instrumentation;
static TrackListActivity activityMytracks;
// Check whether the UI has an action bar which is related with the version of
// Android OS.
static boolean hasActionBar = false;
static boolean isEmulator = true;
static boolean hasGpsSingal = true;
static boolean isCheckedFirstLaunch = false;
static boolean isGooglePlayServicesLatest = true;
public static final String LOG_TAG = "MyTracksTest";
private EndToEndTestUtils() {}
/**
* Checks the language, then sets the fields with right string.
*/
private static void checkLanguage() {
Locale locale = null;
Configuration config=null;
config = activityMytracks.getBaseContext().getResources().getConfiguration();
locale = new Locale("en");
Locale.setDefault(locale);
config.locale = locale;
deviceLanguage = instrumentation.getContext().getResources().getConfiguration().locale.getLanguage();
if (RELATIVE_STARTTIME_POSTFIX_MULTILINGUAL.get(deviceLanguage) != null) {
RELATIVE_STARTTIME_POSTFIX = RELATIVE_STARTTIME_POSTFIX_MULTILINGUAL.get(deviceLanguage);
KM = KM_MULTILINGUAL.get(deviceLanguage);
MILE = MILE_MULTILINGUAL.get(deviceLanguage);
} else {
RELATIVE_STARTTIME_POSTFIX = RELATIVE_STARTTIME_POSTFIX_MULTILINGUAL.get("es");
KM = KM_MULTILINGUAL.get("es");
MILE = MILE_MULTILINGUAL.get("es");
}
}
/**
* Sends Gps data to emulator, and the start value has an offset.
*
* @param number send times
* @param offset is used to compute the start latitude and longitude
* @param pause pause interval between each sending
*/
public static void sendGps(int number, int offset, int pause) {
if (number < 1) {
return;
}
int pauseInterval = PAUSE_DEFAULT;
if (pause != -1) {
pauseInterval = pause;
}
// If it's a real device, does not send simulated GPS signal.
if (!isEmulator) {
return;
}
PrintStream out = null;
Socket socket = null;
try {
socket = new Socket(ANDROID_LOCAL_IP, emulatorPort);
out = new PrintStream(socket.getOutputStream());
double longitude = START_LONGITUDE + offset * DELTA_LONGITUDE;
double latitude = START_LATITUDE + offset * DELTA_LADITUDE;
for (int i = 0; i < number; i++) {
out.println("geo fix " + longitude + " " + latitude);
longitude += DELTA_LONGITUDE;
latitude += DELTA_LADITUDE;
Thread.sleep(pauseInterval);
}
// Wait the GPS signal can be obtained by MyTracks.
Thread.sleep(SHORT_WAIT_TIME);
} catch (UnknownHostException e) {
System.exit(-1);
} catch (IOException e) {
System.exit(-1);
} catch (InterruptedException e) {
System.exit(-1);
} finally {
if (out != null) {
out.close();
}
}
}
/**
* Send Gps data to emulator.
*
* @param number number of signals
* @param offset is used to compute the start latitude and longitude
*/
public static void sendGps(int number, int offset) {
sendGps(number, offset, -1);
}
/**
* Send Gps data to emulator.
*
* @param number number of signals
*/
public static void sendGps(int number) {
sendGps(number, 0, -1);
}
/**
* Sets the status whether the test is run on an emulator or not.
*/
private static void setIsEmulator() {
isEmulator = android.os.Build.MODEL.equals("google_sdk");
}
/**
* Checks whether the Google Play Services need update.
*/
private static boolean isGooglePlayServicesLatest() {
return findTextView("Google Play services") == null;
}
/**
* A setup for debugging end-to-end tests.
*
* @param instrumentation the instrumentation is used for test
* @param activityMyTracks the startup activity
*/
public static void setupForDebug(Instrumentation instrumentation,
TrackListActivity activityMyTracks) {
EndToEndTestUtils.instrumentation = instrumentation;
EndToEndTestUtils.activityMytracks = activityMyTracks;
SOLO = new Solo(EndToEndTestUtils.instrumentation, EndToEndTestUtils.activityMytracks);
setIsEmulator();
hasActionBar = setHasActionBar();
checkLanguage();
}
/**
* A setup for all end-to-end tests.
*
* @param instrumentation the instrumentation is used for test
* @param activityMyTracks the startup activity
*/
public static void setupForAllTest(Instrumentation instrumentation,
TrackListActivity activityMyTracks) {
EndToEndTestUtils.instrumentation = instrumentation;
EndToEndTestUtils.activityMytracks = activityMyTracks;
SOLO = new Solo(EndToEndTestUtils.instrumentation, EndToEndTestUtils.activityMytracks);
if (!isGooglePlayServicesLatest) {
SOLO.finishOpenedActivities();
Assert.fail();
Log.e(LOG_TAG, "Need update Google Play Services");
}
// Check if open MyTracks first time after install. If so, there would be a
// welcome view with accept buttons. And makes sure only check once.
if (!isCheckedFirstLaunch) {
isGooglePlayServicesLatest = isGooglePlayServicesLatest();
if (!isGooglePlayServicesLatest) {
SOLO.finishOpenedActivities();
Assert.fail();
Log.e(LOG_TAG, "Need update Google Play Services");
}
setIsEmulator();
if ((getButtonOnScreen(activityMytracks.getString(R.string.eula_accept),
false, false) != null)) {
verifyFirstLaunch();
} else if (SOLO.waitForText(
// After reset setting, welcome page will show again.
activityMytracks.getString(R.string.welcome_title), 0, SHORT_WAIT_TIME)) {
resetPreferredUnits();
}
hasActionBar = setHasActionBar();
checkLanguage();
isCheckedFirstLaunch = true;
deleteAllTracks();
resetAllSettings(activityMyTracks, false);
instrumentation.waitForIdleSync();
// Check the status of real phone. For emulator, we would fix GPS signal.
if (!isEmulator) {
GoToMyLocationTest.findAndClickMyLocation(activityMyTracks);
hasGpsSingal = !SOLO.waitForText(NO_GPS_MESSAGE_PREFIX, 1,
SHORT_WAIT_TIME);
SOLO.goBack();
}
} else if (SOLO.waitForText(
// After reset setting, welcome page will show again.
activityMytracks.getString(R.string.welcome_title), 0, SHORT_WAIT_TIME)) {
resetPreferredUnits();
}
// Check whether is under recording. If previous test failed, the recording
// may not be recording.
if (isUnderRecording()) {
stopRecording(true);
}
}
/**
* Checks if need reset preferred units.
*/
private static void resetPreferredUnits() {
getButtonOnScreen(activityMytracks.getString(R.string.generic_ok), true, true);
SOLO.waitForText(activityMytracks.getString(R.string.settings_stats_units_title));
getButtonOnScreen(activityMytracks.getString(R.string.generic_ok), true, true);
instrumentation.waitForIdleSync();
}
/**
* Rotates the given activity.
*
* @param activity a given activity
*/
private static void rotateActivity(Activity activity) {
activity
.setRequestedOrientation(activity.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT ? ORIENTATION_LANDSCAPE
: ORIENTATION_PORTRAIT);
}
/**
* Accepts terms and configures units.
*/
private static void verifyFirstLaunch() {
getButtonOnScreen(activityMytracks.getString(R.string.eula_accept), true, true);
if (SOLO.waitForText(activityMytracks.getString(R.string.generic_ok))) {
// Click for welcome.
getButtonOnScreen(activityMytracks.getString(R.string.generic_ok), true, true);
// Click for choose units.
getButtonOnScreen(activityMytracks.getString(R.string.generic_ok), true, true);
instrumentation.waitForIdleSync();
}
}
/**
* Creates a simple track which can be used by subsequent test. This method
* will save a customized track name.
*
* @param numberOfGpsData number of simulated Gps data
* @param showTrackList whether stay on track list activity or track detail
* activity
*/
public static void createSimpleTrack(int numberOfGpsData, boolean showTrackList) {
startRecording();
sendGps(numberOfGpsData);
instrumentation.waitForIdleSync();
stopRecording(true);
instrumentation.waitForIdleSync();
if (showTrackList) {
SOLO.goBack();
}
instrumentation.waitForIdleSync();
}
/**
* Creates a track which contains pause during recording.
*
* @param numberOfGpsData number of simulated Gps data before pause and after resume
*/
public static void createTrackWithPause(int numberOfGpsData) {
startRecording();
sendGps(numberOfGpsData);
pauseRecording();
resumeRecording();
sendGps(numberOfGpsData, numberOfGpsData);
stopRecording(true);
}
/**
* Checks if there is no track in track list. For some tests need at least one
* track, the method can save time to create a new track.
*
* @param isClick if not empty, true means click any track
* @return return true if the track list is empty
*/
public static boolean isTrackListEmpty(boolean isClick) {
int trackNumber = SOLO.getCurrentListViews().get(0).getCount();
if (trackNumber <= 0) {
return true;
}
if (isClick) {
View oneTrack = SOLO.getCurrentListViews().get(0).getChildAt(0);
trackName = (String) ((TextView) oneTrack.findViewById(R.id.list_item_name)).getText();
SOLO.scrollUp();
SOLO.clickOnView(oneTrack);
}
return false;
}
/**
* Create a new track if the track is empty.
*
* @param gpsNumber the number of gps signals
* @param showTrackList whether stay on track list activity or track detail
* activity
*/
public static void createTrackIfEmpty(int gpsNumber, boolean showTrackList) {
if (isTrackListEmpty(!showTrackList)) {
// Create a simple track.
createSimpleTrack(gpsNumber, showTrackList);
}
}
/**
* Starts recoding track.
*/
public static void startRecording() {
View startButton = SOLO.getCurrentActivity().findViewById(R.id.track_controller_record);
if(startButton != null && startButton.isShown()) {
SOLO.clickOnView(startButton);
}
instrumentation.waitForIdleSync();
}
/**
* Pauses recoding track.
*/
public static void pauseRecording() {
View pauseButton = SOLO.getCurrentActivity().findViewById(R.id.track_controller_record);
if(pauseButton != null && pauseButton.isShown()) {
SOLO.clickOnView(pauseButton);
}
instrumentation.waitForIdleSync();
}
/**
* Resume recoding track.
*/
public static void resumeRecording() {
View startButton = SOLO.getCurrentActivity().findViewById(R.id.track_controller_record);
if(startButton != null && startButton.isShown()) {
SOLO.clickOnView(startButton);
}
instrumentation.waitForIdleSync();
}
/**
* Checks if the MyTracks is under recording.
*
* @return true if it is under recording.
*/
public static boolean isUnderRecording() {
instrumentation.waitForIdleSync();
return SOLO.getCurrentActivity().findViewById(R.id.track_controller_stop).isEnabled();
}
/**
* Stops recoding track.
*
* @param isSave true means should save this track
*/
public static void stopRecording(boolean isSave) {
View stopButton = SOLO.getCurrentActivity().findViewById(R.id.track_controller_stop);
if(stopButton != null && stopButton.isShown() ) {
SOLO.clickOnView(stopButton);
if (isSave) {
SOLO.waitForText(activityMytracks.getString(R.string.generic_save), 1, 5000);
// Make every track name is unique to make sure every check can be
// trusted.
trackName = TRACK_NAME_PREFIX
+ System.currentTimeMillis();
SOLO.sendKey(KeyEvent.KEYCODE_DEL);
enterTextAvoidSoftKeyBoard(0, trackName);
enterTextAvoidSoftKeyBoard(1, activityType);
SOLO.clickOnText(activityMytracks.getString(R.string.generic_save));
instrumentation.waitForIdleSync();
}
}
}
/**
* Deletes a kind of track in MyTracks folder.
*
* @param trackKind the kind of track
*/
public static void deleteExportedFiles(String trackKind) {
File[] allFiles = (new File(FileUtils.buildExternalDirectoryPath(trackKind.toLowerCase())))
.listFiles();
if (allFiles != null) {
for (File oneFile : allFiles) {
oneFile.delete();
}
}
}
/**
* Deletes all tracks. This method should be call when the TracksListActivity
* is shown.
*/
public static void deleteAllTracks() {
if (!isTrackListEmpty(false)) {
findMenuItem(activityMytracks.getString(R.string.menu_delete_all), true);
getButtonOnScreen(activityMytracks.getString(R.string.generic_ok), true, true);
}
}
/**
* Gets a kind of exported files.
*
* @param trackKind the kind of track
* @return files array of such kind of exported tracks
*/
public static File[] getExportedFiles(final String trackKind) {
String filePath = FileUtils.buildExternalDirectoryPath(trackKind);
FileFilter filter = new FileFilter() {
@Override
public boolean accept(File pathname) {
return pathname.getName().indexOf("." + trackKind) > 0;
}
};
return (new File(filePath)).listFiles(filter);
}
/**
* Saves a track to a kind of file in SD card.
*
* @param trackKind the kind of track
*/
public static void saveTrackToSdCard(String trackKind) {
deleteExportedFiles(trackKind);
instrumentation.waitForIdleSync();
findMenuItem(activityMytracks.getString(R.string.menu_save), true);
instrumentation.waitForIdleSync();
SOLO.clickOnText(trackKind.toUpperCase());
// rotateAllActivities();
SOLO.waitForText(activityMytracks.getString(R.string.generic_success_title));
}
/**
* Checks if a button is existed in the screen.
*
* @param buttonName the name string of the button
* @param isWait whether wait the text
* @param isClick whether click the button if find it
* @return the button to search, and null means can not find the button
*/
public static View getButtonOnScreen(String buttonName, boolean isWait,boolean isClick) {
View button = null;
instrumentation.waitForIdleSync();
if (isWait) {
SOLO.waitForText(buttonName);
}
// Find on action bar.
if (hasActionBar) {
ArrayList<View> allViews = SOLO.getViews();
for (View view : allViews) {
String className = view.getClass().getName();
if(className.indexOf("ActionMenuItemView") > 0) {
String menuItemNameString = view.getContentDescription().toString();
if(menuItemNameString.equalsIgnoreCase(buttonName)) {
button = view;
break;
}
}
}
}
// Get all buttons and find.
if(button == null) {
ArrayList<Button> currentButtons = SOLO.getCurrentButtons();
for (Button oneButton : currentButtons) {
String title = (String) oneButton.getText();
if (title.equalsIgnoreCase(buttonName)) {
button = oneButton;
}
}
}
if(button != null && isClick) {
SOLO.clickOnView(button);
}
if (button == null && isClick) {
Log.d(LOG_TAG, "Don't find the button " + buttonName);
}
return button;
}
/**
* Checks whether an action bar is shown.
*
* @return false means can not check failed.
*/
private static boolean setHasActionBar() {
try {
return activityMytracks.getActionBar() == null ? false : true;
}catch (Throwable e) {
// For in Android which does not has action bar, here will meet a error.
return false;
}
}
/**
* Rotates the current activity.
*/
public static void rotateCurrentActivity() {
rotateActivity(SOLO.getCurrentActivity());
instrumentation.waitForIdleSync();
}
/**
* Rotates all activities.
*/
public static void rotateAllActivities() {
if (hasActionBar) {
ArrayList<Activity> allActivities = SOLO.getAllOpenedActivities();
for (Activity activity : allActivities) {
rotateActivity(activity);
}
}
instrumentation.waitForIdleSync();
}
/**
* Finds an item in the menu with the option to click the item.
*
* @param menuName the name of item
* @param click true means need click this menu
* @return true if find this menu
*/
public static boolean findMenuItem(String menuName, boolean click) {
boolean findResult = false;
boolean isMoreMenuOpened = false;
// ICS phone.
if (hasActionBar) {
// Firstly find in action bar.
View button = getButtonOnScreen(menuName, false, false);
if (button != null) {
findResult = true;
if (click) {
SOLO.clickOnView(button);
instrumentation.waitForIdleSync();
}
return findResult;
}
showMenuItem();
findResult = SOLO.searchText(menuName, 1, true);
} else {
// Non-ICS phone.
SOLO.sendKey(KeyEvent.KEYCODE_MENU);
if (SOLO.searchText(menuName, 1, true)) {
findResult = true;
} else if (getMoreOptionView() != null) {
SOLO.clickOnView(getMoreOptionView());
findResult = SOLO.searchText(menuName, 1, true);
isMoreMenuOpened = true;
}
}
if (findResult && click) {
SOLO.clickOnView(SOLO.getText(menuName));
instrumentation.waitForIdleSync();
} else {
// Quit more menu list if opened.
if (isMoreMenuOpened) {
SOLO.goBack();
}
// Quit menu list.
SOLO.goBack();
}
return findResult;
}
/**
* Show menu item list.
*/
public static void showMenuItem() {
showMenuItem(0);
}
/**
* Gets more menu items operation is different for different Android OS. When
* get overflow button view on action, it usually be able to click. But in
* some situation, will meet an error when click it. So catch it and try
* again. In most situation, the second click will be pass.
*
* @param depth control the depth of recursion to prevent dead circulation
*/
private static void showMenuItem(int depth) {
// ICS phone.
if (hasActionBar) {
instrumentation.waitForIdleSync();
View moreButton = getMoreOptionView();
// ICS phone without menu key.
if (moreButton != null) {
try {
SOLO.clickOnView(moreButton);
} catch (Throwable e) {
if (depth < 5 && e.getMessage().indexOf("Click can not be completed") > -1) {
showMenuItem(depth++);
}
}
return;
} else {
// ICS phone with menu key.
SOLO.sendKey(KeyEvent.KEYCODE_MENU);
}
} else {
// Non-ICS phone with menu key.
SOLO.sendKey(KeyEvent.KEYCODE_MENU);
}
}
/**
* Finds the more option menu. It should match following conditions:
* <ul>
* <li>The view extends ImageButton.</li>
* <li>The view name equals {@link #MOREOPTION_CLASSNAME}.</li>
* </ul>
* @return the more option view. Null means can not find it.
*/
private static View getMoreOptionView() {
View viewResult = null;
if (hasActionBar) {
ArrayList<View> allViews = SOLO.getViews();
for (View view : allViews) {
if (view instanceof ImageButton && view.getClass().getName().equals(MOREOPTION_CLASSNAME)) {
viewResult = view;
break;
}
}
} else {
ArrayList<View> allViews = SOLO.getViews();
for (View view : allViews) {
if (view.getClass().getName().equals(MENUITEM_CLASSNAME)) {
viewResult = view;
// No break here to get the last menu item.
}
}
}
return viewResult;
}
/**
* Finds a displayed text view with specified text in a view.
*
* @param text text to find
* @param parent which text view in in
* @return the text view, null means can not find it
*/
public static TextView findTextViewInView(String text, View parent) {
ArrayList<TextView> textViews = SOLO.getCurrentTextViews(parent);
for (TextView textView : textViews) {
String textString = (String) textView.getText();
if (textView.isShown() && textString.endsWith(text)) {
return textView;
}
}
return null;
}
/**
* Finds a displayed text view with specified text.
*
* @param text text to find
* @return the text view, null means can not find it
*/
public static TextView findTextView(String text) {
ArrayList<View> allViews = SOLO.getViews();
for (View view : allViews) {
if (view instanceof TextView) {
TextView textView = (TextView) view;
String textString = (String) textView.getText();
if (textView.isShown() && textString.endsWith(text)) {
return textView;
}
}
}
return null;
}
/**
* Finds a displayed text view with specified text and index number.
*
* @param text text to find
* @param index the index to search
* @return the text view, null means can not find it
*/
public static TextView findTextViewByIndex(String text, int index) {
int number = 1;
ArrayList<View> allViews = SOLO.getViews();
for (View view : allViews) {
if (view instanceof TextView) {
TextView textView = (TextView) view;
String textString = (String) textView.getText();
if (textView.isShown() && textString.endsWith(text)) {
if (number == index) {
return textView;
} else {
number++;
}
}
}
}
return null;
}
/**
* Gets the ChartView.
*
* @return the ChartView or null if not find
*/
public static ChartView getChartView() {
ArrayList<View> views = SOLO.getViews();
for (View view : views) {
if (view instanceof ChartView) {
return (ChartView) view;
}
}
return null;
}
/**
* Resets all settings of MyTracks.
*
* @param activityMyTracks current activity
* @param keepInSettingList whether keep in setting list or not
*/
public static void resetAllSettings(Activity activityMyTracks, boolean keepInSettingList) {
findMenuItem(activityMyTracks.getString(R.string.menu_settings), true);
SOLO.waitForText(activityMyTracks.getString(R.string.settings_reset));
SOLO.clickOnText(activityMyTracks.getString(R.string.settings_reset));
getButtonOnScreen(activityMytracks.getString(R.string.generic_ok), true, true);
Assert.assertTrue(SOLO.waitForText(activityMyTracks.getString(R.string.settings_reset_done)));
instrumentation.waitForIdleSync();
if (!keepInSettingList) {
SOLO.goBack();
}
}
/**
* Finds a edit text and enter text in it. This method can hides soft key
* board when input text.
*
* @param editTextIndex the index of edit text
* @param text to enter
*/
public static void enterTextAvoidSoftKeyBoard(int editTextIndex, String text) {
InputMethodManager imm = (InputMethodManager) activityMytracks.getApplicationContext().getSystemService(Context.INPUT_METHOD_SERVICE);
EditText editText = SOLO.getEditText(editTextIndex);
imm.hideSoftInputFromWindow(editText.getWindowToken(), InputMethodManager.HIDE_IMPLICIT_ONLY);
SOLO.enterText(editText, text);
}
/**
* Waits n milliseconds.
*
* @param milliseconds time to sleep
*/
public static void sleep(long milliseconds) {
try {
Thread.sleep(milliseconds);
} catch (InterruptedException e) {
Log.e(LOG_TAG, "Unable to sleep " + milliseconds, e);
}
}
/**
* Checks whether the recording is not started.
*/
static void checkNotRecording() {
instrumentation.waitForIdleSync();
Assert.assertEquals(activityMytracks.getString(R.string.icon_record_track), (String) SOLO
.getCurrentActivity().findViewById(R.id.track_controller_record).getContentDescription());
Assert.assertFalse(SOLO.getCurrentActivity().findViewById(R.id.track_controller_stop)
.isEnabled());
Assert.assertNull(findTextView(activityMytracks.getString(R.string.generic_recording)));
Assert.assertNull(findTextView(activityMytracks.getString(R.string.generic_paused)));
TextView totalTime = (TextView) SOLO.getCurrentActivity().findViewById(R.id.track_controller_total_time);
Assert.assertEquals(StringUtils.formatElapsedTimeWithHour(0), totalTime.getText().toString());
}
/**
* Checks whether the MyTracks is under recording.
*/
static void checkUnderRecording() {
instrumentation.waitForIdleSync();
Assert.assertEquals(activityMytracks.getString(R.string.icon_pause_recording), (String) SOLO
.getCurrentActivity().findViewById(R.id.track_controller_record).getContentDescription());
Assert.assertTrue(SOLO.getCurrentActivity().findViewById(R.id.track_controller_stop)
.isEnabled());
Assert.assertNotNull(findTextView(activityMytracks.getString(R.string.generic_recording)));
Assert.assertNull(findTextView(activityMytracks.getString(R.string.generic_paused)));
String totalTimeOld = ((TextView) SOLO.getCurrentActivity().findViewById(
R.id.track_controller_total_time)).getText().toString();
sleep(2000);
String totalTimeNew = ((TextView) SOLO.getCurrentActivity().findViewById(
R.id.track_controller_total_time)).getText().toString();
Assert.assertFalse(totalTimeOld.equalsIgnoreCase(totalTimeNew));
}
/**
* Checks whether the recording is paused.
*/
static void checkUnderPaused() {
instrumentation.waitForIdleSync();
Assert.assertEquals(activityMytracks.getString(R.string.icon_record_track), (String) SOLO
.getCurrentActivity().findViewById(R.id.track_controller_record).getContentDescription());
Assert.assertTrue(SOLO.getCurrentActivity().findViewById(R.id.track_controller_stop)
.isEnabled());
Assert.assertNull(findTextView(activityMytracks.getString(R.string.generic_recording)));
Assert.assertNotNull(findTextView(activityMytracks.getString(R.string.generic_paused)));
String totalTimeOld = ((TextView) SOLO.getCurrentActivity()
.findViewById(R.id.track_controller_total_time)).getText().toString();
sleep(2000);
String totalTimeNew = ((TextView) SOLO.getCurrentActivity()
.findViewById(R.id.track_controller_total_time)).getText().toString();
Assert.assertTrue(totalTimeOld.equalsIgnoreCase(totalTimeNew));
}
/**
* Creates a way point during track recording.
*
* @param markerNumber of number of previous markers
*/
public static void createWaypoint(int markerNumber) {
findMenuItem(activityMytracks.getString(R.string.menu_markers), true);
if (markerNumber > 0) {
SOLO.waitForText(WAYPOINT_NAME);
int actualMarkerNumber = SOLO.getCurrentListViews().get(0).getCount();
Assert.assertEquals(markerNumber, actualMarkerNumber);
} else {
Assert.assertTrue(SOLO.waitForText(activityMytracks
.getString(R.string.marker_list_empty_message)));
}
findMenuItem(activityMytracks.getString(R.string.menu_insert_marker), true);
enterTextAvoidSoftKeyBoard(0, WAYPOINT_NAME);
SOLO.clickOnButton(activityMytracks.getString(R.string.generic_add));
if (hasGpsSingal) {
Assert.assertTrue(SOLO.waitForText(WAYPOINT_NAME, 1, LONG_WAIT_TIME, true));
} else {
Assert.assertFalse(SOLO.searchText(WAYPOINT_NAME));
}
SOLO.goBack();
}
/**
* Waits a text to disappear.
*/
public static void waitTextToDisappear(String text) {
instrumentation.waitForIdleSync();
SOLO.waitForText(text, 1, VERY_SHORT_WAIT_TIME);
while (SOLO.waitForText(text, 1, VERY_SHORT_WAIT_TIME)) {}
return;
}
}
@@ -1,167 +0,0 @@
/*
* Copyright 2012 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.android.apps.mytracks.endtoendtest;
import com.google.android.apps.mytracks.TrackListActivity;
import com.google.android.apps.mytracks.util.FileUtils;
import com.google.android.maps.mytracks.R;
import android.app.Instrumentation;
import android.test.ActivityInstrumentationTestCase2;
import java.io.File;
/**
* Tests the import and export of MyTracks.
*
* @author Youtao Liu
*/
public class ExportAndImportTest extends ActivityInstrumentationTestCase2<TrackListActivity> {
private Instrumentation instrumentation;
private TrackListActivity activityMyTracks;
public ExportAndImportTest() {
super(TrackListActivity.class);
}
@Override
protected void setUp() throws Exception {
super.setUp();
instrumentation = getInstrumentation();
activityMyTracks = getActivity();
EndToEndTestUtils.setupForAllTest(instrumentation, activityMyTracks);
}
/**
* Tests export and import tracks after creating a track with Gps signal and
* an empty track.
*/
public void testExportAndImportTracks() {
// Create a new track with 3 gps data.
EndToEndTestUtils.createTrackIfEmpty(3, true);
instrumentation.waitForIdleSync();
// Create a empty track.
EndToEndTestUtils.createSimpleTrack(0, true);
instrumentation.waitForIdleSync();
checkExportAndImport();
}
/**
* Tests export and import tracks after creating a track with Gps signal and
* an empty track. Both tracks are paused during recording.
*/
public void testExportAndImportTracks_pause() {
EndToEndTestUtils.deleteAllTracks();
// Create a new track with 3 gps data.
EndToEndTestUtils.createTrackWithPause(3);
instrumentation.waitForIdleSync();
EndToEndTestUtils.SOLO.goBack();
// Create a empty track.
EndToEndTestUtils.createTrackWithPause(0);
instrumentation.waitForIdleSync();
EndToEndTestUtils.SOLO.goBack();
instrumentation.waitForIdleSync();
checkExportAndImport();
}
/**
* Tests export and import tracks.
* <ul>
* <li>Create two tracks, one of them is empty(Have no Gps data).</li>
* <li>Tests import when there is no track file.</li>
* <li>Tests export tracks to Gpx files.</li>
* <li>Tests import files to tracks.</li>
* <li>Tests export tracks to Kml files.</li>
* </ul>
*/
private void checkExportAndImport() {
// Delete all exported gpx and kml tracks.
EndToEndTestUtils.deleteExportedFiles(EndToEndTestUtils.GPX);
EndToEndTestUtils.deleteExportedFiles(EndToEndTestUtils.KML);
int gpxFilesNumber = 0;
File[] allGpxFiles = EndToEndTestUtils.getExportedFiles(EndToEndTestUtils.GPX);
// For the first export, there is no MyTracks folder.
if (allGpxFiles != null) {
gpxFilesNumber = EndToEndTestUtils.getExportedFiles(EndToEndTestUtils.GPX).length;
}
// Get track number in current track list of MyTracks.
int trackNumber = EndToEndTestUtils.SOLO.getCurrentListViews().get(0).getCount();
// No file to imported.
EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_import), true);
EndToEndTestUtils.SOLO.waitForText(activityMyTracks.getString(
R.string.external_storage_import_error_no_file,
FileUtils.buildExternalDirectoryPath(EndToEndTestUtils.GPX)));
EndToEndTestUtils.getButtonOnScreen(activityMyTracks.getString(R.string.generic_ok), true, true);
// Click to export tracks(At least one track) to Gpx files.
EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_save_all), true);
EndToEndTestUtils.SOLO
.clickOnText(String.format(activityMyTracks.getString(R.string.menu_save_format),
EndToEndTestUtils.GPX.toUpperCase()));
EndToEndTestUtils.SOLO.waitForText(
activityMyTracks.getString(R.string.external_storage_save_success));
EndToEndTestUtils.getButtonOnScreen(
activityMyTracks.getString(R.string.generic_ok), true, true);
// Check export file.
assertEquals(gpxFilesNumber + trackNumber,
EndToEndTestUtils.getExportedFiles(EndToEndTestUtils.GPX).length);
instrumentation.waitForIdleSync();
// Click to import track.
gpxFilesNumber = EndToEndTestUtils.getExportedFiles(EndToEndTestUtils.GPX).length;
trackNumber = EndToEndTestUtils.SOLO.getCurrentListViews().get(0).getCount();
EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_import), true);
EndToEndTestUtils.rotateAllActivities();
// Wait for the prefix of import success string is much faster than wait
// the whole string.
EndToEndTestUtils.SOLO.waitForText(
activityMyTracks.getString(R.string.external_storage_import_success_count).split("%")[0]);
// Check import tracks should be equal with the sum of trackNumber and
// gpxFilesNumber;
EndToEndTestUtils.getButtonOnScreen(activityMyTracks.getString(R.string.generic_ok), true, true);
instrumentation.waitForIdleSync();
assertTrue(EndToEndTestUtils.SOLO.waitForText(EndToEndTestUtils.trackName));
assertEquals(trackNumber + gpxFilesNumber, EndToEndTestUtils.SOLO.getCurrentListViews().get(0)
.getCount());
// Click to export tracks(At least two tracks) to KML files.
gpxFilesNumber = EndToEndTestUtils.getExportedFiles(EndToEndTestUtils.GPX).length;
trackNumber = EndToEndTestUtils.SOLO.getCurrentListViews().get(0).getCount();
EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_save_all), true);
EndToEndTestUtils.SOLO
.clickOnText(String.format(activityMyTracks.getString(R.string.menu_save_format),
EndToEndTestUtils.KML.toUpperCase()));
EndToEndTestUtils.SOLO.waitForText(
activityMyTracks.getString(R.string.external_storage_save_success));
EndToEndTestUtils.getButtonOnScreen(
activityMyTracks.getString(R.string.generic_ok), true, true);
// Check export files.
assertEquals(gpxFilesNumber, EndToEndTestUtils.getExportedFiles(EndToEndTestUtils.GPX).length);
assertEquals(trackNumber, EndToEndTestUtils.getExportedFiles(EndToEndTestUtils.KML).length);
}
@Override
protected void tearDown() throws Exception {
EndToEndTestUtils.SOLO.finishOpenedActivities();
super.tearDown();
}
}
@@ -1,101 +0,0 @@
/*
* Copyright 2012 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.android.apps.mytracks.endtoendtest;
import com.google.android.apps.mytracks.TrackListActivity;
import com.google.android.apps.mytracks.util.GoogleLocationUtils;
import com.google.android.maps.mytracks.R;
import android.app.Activity;
import android.app.Instrumentation;
import android.test.ActivityInstrumentationTestCase2;
import android.view.View;
import android.widget.ImageButton;
import java.util.ArrayList;
/**
* Tests the function of go to my location.
*
* @author Youtao Liu
*/
public class GoToMyLocationTest extends ActivityInstrumentationTestCase2<TrackListActivity> {
private Instrumentation instrumentation;
private TrackListActivity activityMyTracks;
public GoToMyLocationTest() {
super(TrackListActivity.class);
}
@Override
protected void setUp() throws Exception {
super.setUp();
instrumentation = getInstrumentation();
activityMyTracks = getActivity();
EndToEndTestUtils.setupForAllTest(instrumentation, activityMyTracks);
}
/**
* Tests the menu My Location.
*/
public void testGotoMyLocation() {
findAndClickMyLocation(activityMyTracks);
if (EndToEndTestUtils.isEmulator) {
String setting = activityMyTracks.getString(
GoogleLocationUtils.isAvailable(activityMyTracks) ? R.string.gps_google_location_settings
: R.string.gps_location_access);
EndToEndTestUtils.SOLO.waitForText(
activityMyTracks.getString(R.string.my_location_no_gps, setting), 1,
EndToEndTestUtils.SHORT_WAIT_TIME);
} else {
// TODO How to verify the location is shown on the map.
}
}
/**
* Finds the My Location view and click it.
*
* @param activity
*/
public static void findAndClickMyLocation(Activity activity) {
EndToEndTestUtils.createTrackIfEmpty(1, false);
EndToEndTestUtils.sendGps(30);
View myLocation = EndToEndTestUtils.SOLO.getCurrentActivity()
.findViewById(R.id.map_my_location);
// Find the My Location button in another if null.
if (myLocation == null) {
ArrayList<ImageButton> aa = EndToEndTestUtils.SOLO.getCurrentImageButtons();
for (ImageButton imageButton : aa) {
if (imageButton.getContentDescription() != null
&& imageButton.getContentDescription().equals(
activity.getString(R.string.icon_my_location))) {
myLocation = imageButton;
break;
}
}
}
EndToEndTestUtils.SOLO.clickOnView(myLocation);
}
@Override
protected void tearDown() throws Exception {
EndToEndTestUtils.SOLO.finishOpenedActivities();
super.tearDown();
}
}
@@ -1,468 +0,0 @@
/*
* Copyright 2012 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.android.apps.mytracks.endtoendtest;
import com.google.android.apps.mytracks.Constants;
import com.google.android.apps.mytracks.io.docs.SendDocsUtils;
import com.google.android.apps.mytracks.io.fusiontables.SendFusionTablesAsyncTask;
import com.google.android.apps.mytracks.io.fusiontables.SendFusionTablesUtils;
import com.google.android.apps.mytracks.io.gdata.GDataClientFactory;
import com.google.android.apps.mytracks.io.gdata.docs.DocumentsClient;
import com.google.android.apps.mytracks.io.gdata.docs.SpreadsheetsClient;
import com.google.android.apps.mytracks.io.gdata.docs.XmlDocsGDataParserFactory;
import com.google.android.apps.mytracks.io.gdata.maps.MapFeatureEntry;
import com.google.android.apps.mytracks.io.gdata.maps.MapsClient;
import com.google.android.apps.mytracks.io.gdata.maps.MapsConstants;
import com.google.android.apps.mytracks.io.gdata.maps.MapsGDataConverter;
import com.google.android.apps.mytracks.io.gdata.maps.MapsMapMetadata;
import com.google.android.apps.mytracks.io.gdata.maps.XmlMapsGDataParserFactory;
import com.google.android.apps.mytracks.util.ApiAdapterFactory;
import com.google.android.apps.mytracks.util.SystemUtils;
import com.google.android.common.gdata.AndroidXmlParserFactory;
import com.google.android.maps.mytracks.R;
import com.google.api.client.googleapis.GoogleHeaders;
import com.google.api.client.googleapis.MethodOverride;
import com.google.api.client.http.GenericUrl;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpResponse;
import com.google.api.client.http.InputStreamContent;
import com.google.wireless.gdata.data.Entry;
import com.google.wireless.gdata.data.Feed;
import com.google.wireless.gdata.parser.GDataParser;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.app.Activity;
import android.content.Context;
import android.util.Log;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
/**
* Provides utilities to access Google Maps, Google Documents, Google Fusion
* Tables.
*
* @author Youtao Liu
*/
public class GoogleUtils {
public static final String DOCUMENT_NAME_PREFIX = "My Tracks";
public static final String SPREADSHEET_NAME = DOCUMENT_NAME_PREFIX + "-" + EndToEndTestUtils.activityType;
/**
* Gets the account to access Google Services.
*
* @param context context used to get account
* @return the first account which is bound with current device
*/
private static Account getAccount(Context context) {
return AccountManager.get(context).getAccountsByType(Constants.ACCOUNT_TYPE)[0];
}
/**
* Gets Google maps of a user.
*
* @param context used to get maps
* @param mapsClient the client to access Google Maps
* @return true means set successfully
*/
private static ArrayList<MapsMapMetadata> getMaps(Context context, MapsClient mapsClient) {
String authToken = null;
ArrayList<String> mapIds = new ArrayList<String>();
ArrayList<MapsMapMetadata> mapData = new ArrayList<MapsMapMetadata>();
try {
authToken = AccountManager.get(context).blockingGetAuthToken(getAccount(context),
MapsConstants.SERVICE_NAME, false);
} catch (Exception e) {
Log.d(EndToEndTestUtils.LOG_TAG, "Unable to get auth token", e);
return mapData;
}
GDataParser gDataParser = null;
try {
gDataParser = mapsClient.getParserForFeed(MapFeatureEntry.class, MapsClient.getMapsFeed(),
authToken);
gDataParser.init();
while (gDataParser.hasMoreData()) {
MapFeatureEntry entry = (MapFeatureEntry) gDataParser.readNextEntry(null);
mapIds.add(MapsGDataConverter.getMapidForEntry(entry));
mapData.add(MapsGDataConverter.getMapMetadataForEntry(entry));
}
} catch (Exception e) {
Log.d(EndToEndTestUtils.LOG_TAG, "Unable to get maps", e);
} finally {
if (gDataParser != null) {
gDataParser.close();
}
}
return mapData;
}
/**
* Searches a map in user's Google Maps.
*
* @param title the title of map
* @param activity activity to get context
* @param isDelete whether delete the map of this track in the Google Maps
* @return true means find the map
*/
private static boolean searchMapByTitle(String title, Activity activity, boolean isDelete) {
Context context = activity.getApplicationContext();
MapsClient mapsClient = new MapsClient(GDataClientFactory.getGDataClient(context),
new XmlMapsGDataParserFactory(new AndroidXmlParserFactory()));
ArrayList<MapsMapMetadata> mapData = getMaps(context, mapsClient);
for (MapsMapMetadata oneData : mapData) {
if (oneData.getDescription().indexOf(DOCUMENT_NAME_PREFIX) > -1
&& oneData.getTitle().equals(title)) {
if (isDelete) {
try {
mapsClient.deleteEntry(oneData.getGDataEditUri(), AccountManager.get(context).blockingGetAuthToken(getAccount(context),
MapsConstants.SERVICE_NAME, false));
return true;
} catch (Exception e) {
Log.d(EndToEndTestUtils.LOG_TAG, "Unable to drop map", e);
return false;
}
}
return true;
}
}
return false;
}
/**
* Searches a map in user's Google Maps.
*
* @param title the title of map
* @param activity activity to get context
* @return true means find the map
*/
public static boolean searchMap(String title, Activity activity) {
return searchMapByTitle(title, activity, false);
}
/**
* Searches a map in user's Google Maps and then delete it.
*
* @param title the title of map
* @param activity activity to get context
* @return true means find the map and delete it successfully
*/
public static boolean deleteMap(String title, Activity activity) {
return searchMapByTitle(title, activity, true);
}
/**
* Searches a doc in user's Google Documents.
*
* @param title the title of doc
* @param activity to get context
* @return the entry of the document, null means can not find the spreadsheet.
*/
public static Entry searchSpreadsheetByTitle(String title, Activity activity) {
Context context = activity.getApplicationContext();
DocumentsClient documentsClient = new DocumentsClient(
GDataClientFactory.getGDataClient(context),
new XmlDocsGDataParserFactory(new AndroidXmlParserFactory()));
try {
String documentsAuthToken = AccountManager.get(context)
.blockingGetAuthToken(getAccount(context), documentsClient.getServiceName(), false);
String uri = String.format(Locale.US, SendDocsUtils.GET_SPREADSHEET_BY_TITLE_URI,
URLEncoder.encode(title, "utf-8"));
GDataParser gDataParser = documentsClient.getParserForFeed(Entry.class, uri,
documentsAuthToken);
gDataParser.init();
while (gDataParser.hasMoreData()) {
Entry entry = gDataParser.readNextEntry(null);
String entryTitle = entry.getTitle();
if (entryTitle.equals(title)) {
return entry;
}
}
} catch (Exception e) {
Log.d(EndToEndTestUtils.LOG_TAG, "Unable to fetch spreadsheet.", e);
}
return null;
}
/**
* Delete spreadsheet which name is title.
*
* @param title the name of spreadsheet
* @param activity to get context
*/
public static void deleteSpreadsheetByTitle(String title, Activity activity) {
Context context = activity.getApplicationContext();
DocumentsClient documentsClient = new DocumentsClient(
GDataClientFactory.getGDataClient(context), new XmlDocsGDataParserFactory(
new AndroidXmlParserFactory()));
try {
String documentsAuthToken = AccountManager.get(context).blockingGetAuthToken(
getAccount(context), documentsClient.getServiceName(), false);
String uri = String.format(Locale.US, SendDocsUtils.GET_SPREADSHEET_BY_TITLE_URI,
URLEncoder.encode(title, "utf-8"));
GDataParser gDataParser = documentsClient.getParserForFeed(Entry.class, uri,
documentsAuthToken);
gDataParser.init();
while (gDataParser.hasMoreData()) {
Entry entry = gDataParser.readNextEntry(null);
String entryTitle = entry.getTitle();
if (entryTitle.equals(title)) {
documentsClient.deleteEntry(entry.getEditUri(), documentsAuthToken);
Log.d(EndToEndTestUtils.LOG_TAG, "Delete one spreadsheet.");
}
}
} catch (Exception e) {
Log.e(EndToEndTestUtils.LOG_TAG, "Unable to fetch spreadsheet.", e);
}
}
/**
* Searches docs in user's Google Documents.
*
* @param title the title of doc
* @param activity to get context
* @return the entry of the document, null means can not find the spreadsheet.
*/
public static List<Entry> searchAllSpreadsheetByTitle(String title, Activity activity) {
List<Entry> docs = new ArrayList<Entry>();
Context context = activity.getApplicationContext();
DocumentsClient documentsClient = new DocumentsClient(
GDataClientFactory.getGDataClient(context),
new XmlDocsGDataParserFactory(new AndroidXmlParserFactory()));
try {
String documentsAuthToken = AccountManager.get(context)
.blockingGetAuthToken(getAccount(context), documentsClient.getServiceName(), false);
String uri = String.format(Locale.US, SendDocsUtils.GET_SPREADSHEET_BY_TITLE_URI,
URLEncoder.encode(title, "utf-8"));
GDataParser gDataParser = documentsClient.getParserForFeed(Entry.class, uri,
documentsAuthToken);
gDataParser.init();
while (gDataParser.hasMoreData()) {
Entry entry = gDataParser.readNextEntry(null);
String entryTitle = entry.getTitle();
if (entryTitle.equals(title)) {
docs.add(entry);
}
}
} catch (Exception e) {
Log.d(EndToEndTestUtils.LOG_TAG, "Unable to fetch spreadsheet.", e);
}
return docs;
}
/**
* Searches a track title in a spreadsheet.
*
* @param title the track name to search
* @param activity to get context
* @param spreadsheetTitle the title of spreadsheet
* @param isDelete whether delete the information of this track in the document
* @return true means find the track name in the spreadsheet
*/
private static boolean searchTrackTitleInSpreadsheet(String title, Activity activity, String spreadsheetTitle, boolean isDelete) {
String spreadsheetId = searchSpreadsheetByTitle(spreadsheetTitle, activity).getId().replace(SendDocsUtils.SPREADSHEET_ID_PREFIX, "");
if(spreadsheetId == null) {
Log.d(EndToEndTestUtils.LOG_TAG, "Unable to find the spreadsheet -- " + spreadsheetTitle);
return false;
}
Context context = activity.getApplicationContext();
try {
SpreadsheetsClient spreadsheetsClient = new SpreadsheetsClient(
GDataClientFactory.getGDataClient(context), new XmlDocsGDataParserFactory(new AndroidXmlParserFactory()));
String spreadsheetsAuthToken = AccountManager.get(activity.getApplicationContext()).blockingGetAuthToken(
getAccount(context), spreadsheetsClient.getServiceName(), false);
String weekSheetId = SendDocsUtils.getWorksheetId(spreadsheetId, spreadsheetsClient, spreadsheetsAuthToken);
String worksheetUri = String.format(Locale.US, SendDocsUtils.GET_WORKSHEET_URI, URLEncoder.encode(spreadsheetId, "utf-8"),
weekSheetId);
GDataParser gDataParser = spreadsheetsClient.getParserForFeed(Feed.class, worksheetUri,
spreadsheetsAuthToken);
gDataParser.init();
while (gDataParser.hasMoreData()) {
Entry entry = gDataParser.readNextEntry(null);
String entryTitle = entry.getTitle();
if (entryTitle.indexOf(title) > -1) {
if (isDelete) {
spreadsheetsClient.deleteEntry(entry.getEditUri(), spreadsheetsAuthToken);
}
return true;
}
}
} catch (Exception e) {
Log.d(EndToEndTestUtils.LOG_TAG, "Unable to fetch content of spreadsheet.", e);
}
return false;
}
/**
* Searches a track in spreadsheet.
*
* @param title the track name to search
* @param activity to get context
* @return true means find the track name in the spreadsheet
*/
public static boolean searchTrackInSpreadSheet(String title, Activity activity) {
return searchTrackTitleInSpreadsheet(title, activity, GoogleUtils.SPREADSHEET_NAME, false);
}
/**
* Searches and deletes a track in spreadsheet.
*
* @param title the track name to search
* @param activity to get context
* @return true means find and delete successfully
*/
public static boolean deleteTrackInSpreadSheet(String title, Activity activity) {
return searchTrackTitleInSpreadsheet(title, activity, GoogleUtils.SPREADSHEET_NAME, true);
}
/**
* Searches a fusion table in user's Google tables.
*
* @param title the title of fusion table
* @param activity to get context
* @return true means find the fusion table
*/
public static boolean searchFusionTableByTitle(String title, Activity activity) {
Context context = activity.getApplicationContext();
try {
HttpResponse response = sendFusionTableQuery("SHOW TABLES", context);
// We can use index of method to check new table for every track name is unique.
if (response != null && response.parseAsString().indexOf(title) > 0) {
return true;
}
} catch (Exception e) {
Log.d(EndToEndTestUtils.LOG_TAG, "Unable to query fusion table.", e);
}
return false;
}
/**
* Drops one fusion table which contain the string in title of current user.
*
* @param title the title of a track to drop
* @param activity to get context
* @return the result of drop
*/
public static boolean dropFusionTables(String title, Activity activity) {
Context context = activity.getApplicationContext();
HttpResponse response = sendFusionTableQuery("SHOW TABLES", context);
String[] rowsTable;
try {
rowsTable = response.parseAsString().split("\n");
for (String row : rowsTable) {
String firstColumn = row.split(",")[0];
String secondColumn = row.split(",")[1];
// The first column is the table id.
if (secondColumn.equals(title)) {
sendFusionTableQuery("DROP TABLE " + firstColumn, context);
return true;
}
}
} catch (IOException e) {
Log.d(EndToEndTestUtils.LOG_TAG, "Failed when delete all fusion tables.", e);
}
return false;
}
/**
* Sends query to operate fusion tables.
*
* @param query to executed
* @param context application context
* @return the response of execution
*/
private static HttpResponse sendFusionTableQuery(String query, Context context) {
try {
String fusionTableAuthToken = AccountManager.get(context).blockingGetAuthToken(getAccount(context),
SendFusionTablesUtils.SERVICE, false);
GenericUrl url = new GenericUrl(SendFusionTablesAsyncTask.FUSION_TABLES_BASE_URL);
String sql = "sql=" + query;
ByteArrayInputStream inputStream = new ByteArrayInputStream(sql.getBytes());
InputStreamContent inputStreamContent = new InputStreamContent(null, inputStream);
HttpRequest request;
request = (ApiAdapterFactory.getApiAdapter().getHttpTransport()
.createRequestFactory(new MethodOverride())).buildPostRequest(url, inputStreamContent);
GoogleHeaders headers = new GoogleHeaders();
headers.setApplicationName(SendFusionTablesAsyncTask.APP_NAME_PREFIX
+ SystemUtils.getMyTracksVersion(context));
headers.setGDataVersion(SendFusionTablesAsyncTask.GDATA_VERSION);
headers.setGoogleLogin(fusionTableAuthToken);
headers.setContentType(SendFusionTablesAsyncTask.CONTENT_TYPE);
request.setHeaders(headers);
HttpResponse response;
response = request.execute();
return response;
} catch (Exception e) {
Log.d(EndToEndTestUtils.LOG_TAG, "Failed when send fusion table query.", e);
return null;
}
}
/**
* Checks whether the status of account is right to use.
*
* @return true means the status of account is good for sending
*/
public static boolean isAccountAvailable() {
// Check whether no account is binded with this device.
if (EndToEndTestUtils.SOLO.waitForText(
EndToEndTestUtils.activityMytracks.getString(R.string.send_google_no_account_title), 1,
EndToEndTestUtils.SHORT_WAIT_TIME)) {
EndToEndTestUtils.getButtonOnScreen(EndToEndTestUtils.activityMytracks.getString(R.string.generic_ok), true,
true);
return false;
}
// Check whether need to choose account.
if (EndToEndTestUtils.SOLO.waitForText(
EndToEndTestUtils.activityMytracks.getString(R.string.send_google_choose_account_title), 1,
EndToEndTestUtils.SHORT_WAIT_TIME)) {
EndToEndTestUtils.getButtonOnScreen(EndToEndTestUtils.activityMytracks.getString(R.string.generic_ok), false,
true);
}
// Check whether no account permission.
if (EndToEndTestUtils.SOLO.waitForText(
EndToEndTestUtils.activityMytracks.getString(R.string.send_google_no_account_permission), 1,
EndToEndTestUtils.SHORT_WAIT_TIME)) {
return false;
}
return true;
}
}
@@ -1,218 +0,0 @@
/*
* Copyright 2012 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.android.apps.mytracks.endtoendtest;
import com.google.android.apps.mytracks.TrackListActivity;
import com.google.android.maps.mytracks.R;
import android.app.Instrumentation;
import android.content.Intent;
import android.test.ActivityInstrumentationTestCase2;
import android.view.KeyEvent;
import android.view.View;
import java.util.ArrayList;
/**
* Tests some menu items of MyTracks.
*
* @author Youtao Liu
*/
public class MenuItemsTest extends ActivityInstrumentationTestCase2<TrackListActivity> {
private Instrumentation instrumentation;
private TrackListActivity activityMyTracks;
private final static String SHARE_ITEM_PARENT_VIEW_NAME = "RecycleListView";
public MenuItemsTest() {
super(TrackListActivity.class);
}
@Override
protected void setUp() throws Exception {
super.setUp();
instrumentation = getInstrumentation();
activityMyTracks = getActivity();
EndToEndTestUtils.setupForAllTest(instrumentation, activityMyTracks);
}
/**
* Tests following items in More menu.
* <ul>
* <li>Tests the aggregated statistics activity.</li>
* <li>Tests the Sensor state activity.</li>
* <li>Tests the help menu.</li>
* </ul>
*/
public void testSomeMenuItems() {
// Menu in TrackListActivity.
EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_aggregated_statistics),
true);
EndToEndTestUtils.SOLO.waitForText(activityMyTracks.getString(R.string.stats_distance));
EndToEndTestUtils.SOLO.goBack();
instrumentation.waitForIdleSync();
EndToEndTestUtils.createTrackIfEmpty(1, false);
instrumentation.waitForIdleSync();
// Menu in TrackDetailActivity.
// When there is no sensor connected this menu will be hidden.
if (EndToEndTestUtils
.findMenuItem(activityMyTracks.getString(R.string.menu_sensor_state), true)) {
EndToEndTestUtils.SOLO.waitForText(activityMyTracks
.getString(R.string.sensor_state_last_sensor_time));
}
EndToEndTestUtils.SOLO.goBack();
EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_help), true);
EndToEndTestUtils.getButtonOnScreen(activityMyTracks.getString(R.string.help_about), true, true);
EndToEndTestUtils.getButtonOnScreen(activityMyTracks.getString(R.string.generic_ok), true, true);
EndToEndTestUtils.getButtonOnScreen(activityMyTracks.getString(R.string.generic_ok), true, true);
}
/**
* Tests search menu item.
*/
public void testSearch() {
EndToEndTestUtils.createSimpleTrack(0, true);
EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_search), true);
EndToEndTestUtils.enterTextAvoidSoftKeyBoard(0, EndToEndTestUtils.trackName);
sendKeys(KeyEvent.KEYCODE_ENTER);
instrumentation.waitForIdleSync();
assertEquals(1, EndToEndTestUtils.SOLO.getCurrentListViews().size());
}
/**
* Tests the share menu item. This test to check whether crash will happen during the share.
*/
public void testShareActivity() {
// Try all share items.
for (int i = 0;; i++) {
EndToEndTestUtils.createTrackIfEmpty(0, false);
View oneItemView = findShareItem(i);
if (oneItemView == null) {
break;
}
EndToEndTestUtils.SOLO.clickOnView(oneItemView);
EndToEndTestUtils.getButtonOnScreen(activityMyTracks.getString(R.string.generic_ok), true,
true);
if(!GoogleUtils.isAccountAvailable()) {
break;
}
// Waiting the send is finish.
while (EndToEndTestUtils.SOLO.waitForText(
activityMyTracks.getString(R.string.generic_progress_title), 1,
EndToEndTestUtils.SHORT_WAIT_TIME)) {}
// Check whether data is correct on Google Map and then delete it.
assertTrue(GoogleUtils.deleteMap(EndToEndTestUtils.trackName, activityMyTracks));
// Display the MyTracks activity for the share item may startup other
// applications.
Intent intent = new Intent();
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setClass(activityMyTracks.getApplicationContext(), TrackListActivity.class);
activityMyTracks.getApplicationContext().startActivity(intent);
EndToEndTestUtils.sleep(EndToEndTestUtils.NORMAL_WAIT_TIME);
}
}
/**
* Gets the view to click the share item by item index.
*
* @param index of a share item
* @return null when no such item
*/
private View findShareItem(int index) {
EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_share), true);
ArrayList<View> views = EndToEndTestUtils.SOLO.getViews();
int i = 0;
for (View view : views) {
String name = view.getParent().getClass().getName();
// Each share item is a child of a "RecycleListView"
if (name.indexOf(SHARE_ITEM_PARENT_VIEW_NAME) > 0) {
if (index == i) {
return view;
}
i++;
}
}
return null;
}
/**
* Checks the voice frequency and split frequency menus during recording. When
* recording, they should be in both the menu and the recording settings. When
* not recording, they should only be in the recording settings.
*/
public void testFrequencyMenu() {
EndToEndTestUtils.startRecording();
assertTrue(EndToEndTestUtils.findMenuItem(
activityMyTracks.getString(R.string.menu_voice_frequency), false));
assertTrue(EndToEndTestUtils.findMenuItem(
activityMyTracks.getString(R.string.menu_split_frequency), false));
EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_settings), true);
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.settings_recording));
assertTrue(EndToEndTestUtils.SOLO.searchText(activityMyTracks.getString(R.string.menu_voice_frequency), 1, true, true));
assertTrue(EndToEndTestUtils.SOLO.searchText(activityMyTracks.getString(R.string.menu_split_frequency), 1, true, true));
EndToEndTestUtils.SOLO.goBack();
EndToEndTestUtils.SOLO.goBack();
EndToEndTestUtils.stopRecording(true);
assertFalse(EndToEndTestUtils.findMenuItem(
activityMyTracks.getString(R.string.menu_voice_frequency), false));
assertFalse(EndToEndTestUtils.findMenuItem(
activityMyTracks.getString(R.string.menu_split_frequency), false));
EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_settings), true);
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.settings_recording));
assertTrue(EndToEndTestUtils.SOLO.searchText(activityMyTracks.getString(R.string.menu_voice_frequency), 1, true, true));
assertTrue(EndToEndTestUtils.SOLO.searchText(activityMyTracks.getString(R.string.menu_split_frequency), 1, true, true));
}
/**
* Tests starting and stopping GPS.
*/
public void testGPSMenu() {
boolean GPSStatus = EndToEndTestUtils.findMenuItem(
activityMyTracks.getString(R.string.menu_stop_gps), false);
// Following starting/stopping or stopping/starting GPS.
EndToEndTestUtils.findMenuItem(GPSStatus ? activityMyTracks.getString(R.string.menu_stop_gps)
: activityMyTracks.getString(R.string.menu_start_gps), true);
GPSStatus = !GPSStatus;
EndToEndTestUtils.waitTextToDisappear(GPSStatus ? activityMyTracks
.getString(R.string.menu_start_gps) : activityMyTracks.getString(R.string.menu_stop_gps));
assertEquals(GPSStatus,
EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_stop_gps), false));
EndToEndTestUtils.findMenuItem(GPSStatus ? activityMyTracks.getString(R.string.menu_stop_gps)
: activityMyTracks.getString(R.string.menu_start_gps), true);
GPSStatus = !GPSStatus;
EndToEndTestUtils.waitTextToDisappear(GPSStatus ? activityMyTracks
.getString(R.string.menu_start_gps) : activityMyTracks.getString(R.string.menu_stop_gps));
assertEquals(GPSStatus,
EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_stop_gps), false));
}
@Override
protected void tearDown() throws Exception {
EndToEndTestUtils.SOLO.finishOpenedActivities();
super.tearDown();
}
}
@@ -1,154 +0,0 @@
/*
* Copyright 2012 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.android.apps.mytracks.endtoendtest;
import com.google.android.apps.mytracks.TrackListActivity;
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
import com.google.android.apps.mytracks.content.MyTracksProviderUtils.LocationIterator;
import com.google.android.apps.mytracks.services.TrackRecordingService;
import android.app.Instrumentation;
import android.location.Location;
import android.test.ActivityInstrumentationTestCase2;
/**
* Tests the pause and resume of recording.
*
* @author Youtao Liu
*/
public class PauseRecordingTest extends ActivityInstrumentationTestCase2<TrackListActivity> {
private Instrumentation instrumentation;
private TrackListActivity activityMyTracks;
public PauseRecordingTest() {
super(TrackListActivity.class);
}
@Override
protected void setUp() throws Exception {
super.setUp();
instrumentation = getInstrumentation();
activityMyTracks = getActivity();
EndToEndTestUtils.setupForAllTest(instrumentation, activityMyTracks);
}
/**
* Tests the pause recording feature. Stops the recording after pause.
*/
public void testPauseRecording_stopAfterPause() {
int gpsSignalNumber = 3;
EndToEndTestUtils.checkNotRecording();
// Start recording
EndToEndTestUtils.startRecording();
EndToEndTestUtils.checkUnderRecording();
EndToEndTestUtils.sendGps(gpsSignalNumber);
// Pause
EndToEndTestUtils.pauseRecording();
EndToEndTestUtils.checkUnderPaused();
EndToEndTestUtils.sendGps(gpsSignalNumber, gpsSignalNumber);
// Stop
EndToEndTestUtils.stopRecording(true);
checkPointsInPausedTrack(gpsSignalNumber, 1, 0);
EndToEndTestUtils.SOLO.goBack();
EndToEndTestUtils.checkNotRecording();
}
/**
* Tests the pause recording feature. Stops the recording after resume.
*/
public void testPauseRecording_stopAfterResume() {
int gpsSignalNumber = 3;
EndToEndTestUtils.checkNotRecording();
// Start recording
EndToEndTestUtils.startRecording();
EndToEndTestUtils.checkUnderRecording();
EndToEndTestUtils.sendGps(gpsSignalNumber);
// Pause
EndToEndTestUtils.pauseRecording();
EndToEndTestUtils.checkUnderPaused();
// Send Gps signal after pause.
// Add 10 to make these signals are apparently different.
EndToEndTestUtils.sendGps(gpsSignalNumber, gpsSignalNumber + 10, 10);
// Resume
EndToEndTestUtils.resumeRecording();
EndToEndTestUtils.checkUnderRecording();
EndToEndTestUtils.sendGps(gpsSignalNumber, gpsSignalNumber);
// Stop
EndToEndTestUtils.stopRecording(true);
checkPointsInPausedTrack(gpsSignalNumber * 2, 1, 1);
EndToEndTestUtils.SOLO.goBack();
EndToEndTestUtils.checkNotRecording();
}
/**
* Check the points in the last track.
*
* @param expectPointNumber the number of location points
* @param expectPauseNumber the number of pause points
* @param expectResumeNumber the number of resume points
*/
private void checkPointsInPausedTrack(int expectPointNumber, int expectPauseNumber,
int expectResumeNumber) {
if (EndToEndTestUtils.isEmulator) {
int numberOfPoints = 0;
int numberOfPausePoint = 0;
int numberOfResumePoint = 0;
MyTracksProviderUtils providerUtils = MyTracksProviderUtils.Factory.get(activityMyTracks
.getApplicationContext());
long trackId = providerUtils.getLastTrack().getId();
LocationIterator points = providerUtils.getTrackPointLocationIterator(trackId, 0, false,
MyTracksProviderUtils.DEFAULT_LOCATION_FACTORY);
while (points.hasNext()) {
Location onePoint = points.next();
double latitude = onePoint.getLatitude();
double longitude = onePoint.getLongitude();
if (latitude == TrackRecordingService.PAUSE_LATITUDE) {
numberOfPausePoint++;
} else if (latitude == TrackRecordingService.RESUME_LATITUDE) {
numberOfResumePoint++;
} else {
assertEquals(numberOfPoints, (int) ((latitude - EndToEndTestUtils.START_LATITUDE)
/ EndToEndTestUtils.DELTA_LADITUDE + 0.5));
assertEquals(numberOfPoints, (int) ((longitude - EndToEndTestUtils.START_LONGITUDE)
/ EndToEndTestUtils.DELTA_LONGITUDE + 0.5));
numberOfPoints++;
}
}
assertEquals(expectPointNumber, numberOfPoints);
assertEquals(expectPauseNumber, numberOfPausePoint);
assertEquals(expectResumeNumber, numberOfResumePoint);
}
}
@Override
protected void tearDown() throws Exception {
EndToEndTestUtils.SOLO.finishOpenedActivities();
super.tearDown();
}
}
@@ -1,84 +0,0 @@
/*
* Copyright 2012 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.android.apps.mytracks.endtoendtest;
import com.google.android.apps.mytracks.TrackListActivity;
import android.app.Instrumentation;
import android.test.ActivityInstrumentationTestCase2;
/**
* Tests sending a track to SD card.
*
* @author Youtao Liu
*/
public class SaveToSdCardTest extends ActivityInstrumentationTestCase2<TrackListActivity> {
private Instrumentation instrumentation;
private TrackListActivity activityMyTracks;
public SaveToSdCardTest() {
super(TrackListActivity.class);
}
@Override
protected void setUp() throws Exception {
super.setUp();
instrumentation = getInstrumentation();
activityMyTracks = getActivity();
EndToEndTestUtils.setupForAllTest(instrumentation, activityMyTracks);
EndToEndTestUtils.createTrackIfEmpty(1, false);
}
/**
* Tests saving a track to SD card as a GPX file.
*/
public void testSaveToSdCard_GPX() {
EndToEndTestUtils.saveTrackToSdCard(EndToEndTestUtils.GPX);
assertEquals(1, EndToEndTestUtils.getExportedFiles(EndToEndTestUtils.GPX).length);
}
/**
* Tests saving a track to SD card as a KML file.
*/
public void testSaveToSdCard_KML() {
EndToEndTestUtils.saveTrackToSdCard(EndToEndTestUtils.KML);
assertEquals(1, EndToEndTestUtils.getExportedFiles(EndToEndTestUtils.KML).length);
}
/**
* Tests saving a track to SD card as a CSV file.
*/
public void testSaveToSdCard_CSV() {
EndToEndTestUtils.saveTrackToSdCard(EndToEndTestUtils.CSV);
assertEquals(1, EndToEndTestUtils.getExportedFiles(EndToEndTestUtils.CSV).length);
}
/**
* Tests saving a track to SD card as a TCX file.
*/
public void testSaveToSdCard_TCX() {
EndToEndTestUtils.saveTrackToSdCard(EndToEndTestUtils.TCX);
assertEquals(1, EndToEndTestUtils.getExportedFiles(EndToEndTestUtils.TCX).length);
}
@Override
protected void tearDown() throws Exception {
EndToEndTestUtils.SOLO.finishOpenedActivities();
super.tearDown();
}
}
@@ -1,168 +0,0 @@
/*
* Copyright 2012 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.android.apps.mytracks.endtoendtest;
import com.google.android.apps.mytracks.TrackListActivity;
import com.google.android.maps.mytracks.R;
import com.google.wireless.gdata.data.Entry;
import android.annotation.TargetApi;
import android.app.Instrumentation;
import android.test.ActivityInstrumentationTestCase2;
import android.widget.CheckBox;
import java.util.ArrayList;
import java.util.List;
/**
* Tests the logic of send track to Google.
*
* @author Youtao Liu
*/
public class SendToGoogleTest extends ActivityInstrumentationTestCase2<TrackListActivity> {
private Instrumentation instrumentation;
private TrackListActivity activityMyTracks;
@TargetApi(15)
public SendToGoogleTest() {
super(TrackListActivity.class);
}
@Override
protected void setUp() throws Exception {
super.setUp();
instrumentation = getInstrumentation();
activityMyTracks = getActivity();
EndToEndTestUtils.setupForAllTest(instrumentation, activityMyTracks);
}
/**
* Check all services and send to google.
*/
public void testCreateAndSendTrack_send() {
EndToEndTestUtils.createTrackIfEmpty(1, false);
instrumentation.waitForIdleSync();
checkSendTrackToGoogle();
}
/**
* Check all services and send to google.
*/
public void testCreateAndSendTrack_sendPausedTrack() {
EndToEndTestUtils.deleteAllTracks();
EndToEndTestUtils.createTrackWithPause(3);
instrumentation.waitForIdleSync();
checkSendTrackToGoogle();
}
/**
* Sends two tracks with same activity. Two tracks should be in the same
* spreadsheet.
*/
public void testSendTwoTracksWithSameActivity() {
String testActivity = "(TestActivity)";
EndToEndTestUtils.activityType = testActivity;
GoogleUtils.deleteSpreadsheetByTitle("My Tracks-" + EndToEndTestUtils.activityType,
EndToEndTestUtils.activityMytracks);
EndToEndTestUtils.createSimpleTrack(1, false);
boolean result = sendToGoogle();
result = result && sendToGoogle();
// Result is true mean has account bound with this device and send
// successful.
if (result) {
List<Entry> spreadsheetEntry = GoogleUtils
.searchAllSpreadsheetByTitle(GoogleUtils.DOCUMENT_NAME_PREFIX + "-"
+ EndToEndTestUtils.activityType, activityMyTracks);
assertEquals(1, spreadsheetEntry.size());
}
}
/**
* Checks the process of sending track to google.
*/
private void checkSendTrackToGoogle() {
if (!sendToGoogle()) {
return;
}
// Check whether all data is correct on Google Map, Documents, and
// Spreadsheet.
assertTrue(GoogleUtils.deleteMap(EndToEndTestUtils.trackName, activityMyTracks));
assertTrue(GoogleUtils.searchFusionTableByTitle(EndToEndTestUtils.TRACK_NAME_PREFIX,
activityMyTracks));
assertTrue(GoogleUtils.deleteTrackInSpreadSheet(EndToEndTestUtils.trackName, activityMyTracks));
assertTrue(GoogleUtils.dropFusionTables(EndToEndTestUtils.trackName, activityMyTracks));
}
/**
* Sends a track to Google.
*
* @return true means send successfully
*/
private boolean sendToGoogle() {
EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_send_google), true);
EndToEndTestUtils.SOLO.waitForText(activityMyTracks.getString(R.string.send_google_title));
ArrayList<CheckBox> checkBoxs = EndToEndTestUtils.SOLO.getCurrentCheckBoxes();
for (int i = 0; i < checkBoxs.size(); i++) {
if (!checkBoxs.get(i).isChecked()) {
EndToEndTestUtils.SOLO.clickOnCheckBox(i);
}
}
if (checkBoxs.size() < 3) {
EndToEndTestUtils.SOLO.scrollDown();
checkBoxs = EndToEndTestUtils.SOLO.getCurrentCheckBoxes();
// Choose all Google service.
for (int i = 0; i < checkBoxs.size(); i++) {
if (!checkBoxs.get(i).isChecked()) {
EndToEndTestUtils.SOLO.clickOnCheckBox(i);
}
}
}
instrumentation.waitForIdleSync();
EndToEndTestUtils.getButtonOnScreen(activityMyTracks.getString(R.string.send_google_send_now),
true, true);
if (!GoogleUtils.isAccountAvailable()) {
return false;
}
// Following check the process of "Send to Google".
assertTrue(EndToEndTestUtils.SOLO.waitForText(activityMyTracks
.getString(R.string.generic_progress_title)));
// Waiting the send is finish.
while (EndToEndTestUtils.SOLO.waitForText(
activityMyTracks.getString(R.string.generic_progress_title), 1,
EndToEndTestUtils.SHORT_WAIT_TIME)) {}
// Check whether the result dialog is display.
assertTrue(EndToEndTestUtils.SOLO.waitForText(activityMyTracks
.getString(R.string.share_track_share_url)));
EndToEndTestUtils
.getButtonOnScreen(activityMyTracks.getString(R.string.generic_ok), true, true);
return true;
}
@Override
protected void tearDown() throws Exception {
EndToEndTestUtils.activityType = EndToEndTestUtils.DEFAULTACTIVITYTYPE;
EndToEndTestUtils.SOLO.finishOpenedActivities();
super.tearDown();
}
}
@@ -1,370 +0,0 @@
/*
* Copyright 2012 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.android.apps.mytracks.endtoendtest;
import com.google.android.apps.mytracks.ChartView;
import com.google.android.apps.mytracks.TrackListActivity;
import com.google.android.apps.mytracks.util.PreferencesUtils;
import com.google.android.maps.mytracks.R;
import android.app.Instrumentation;
import android.content.Context;
import android.test.ActivityInstrumentationTestCase2;
import android.widget.CheckBox;
import java.util.ArrayList;
/**
* Tests the setting of MyTracks.
*
* @author Youtao Liu
*/
public class SettingTest extends ActivityInstrumentationTestCase2<TrackListActivity> {
private Instrumentation instrumentation;
private TrackListActivity activityMyTracks;
public SettingTest() {
super(TrackListActivity.class);
}
@Override
protected void setUp() throws Exception {
super.setUp();
instrumentation = getInstrumentation();
activityMyTracks = getActivity();
EndToEndTestUtils.setupForDebug(instrumentation, activityMyTracks);
}
/**
* Changes some settings and then reset them. This test case tests three
* points:
* <ul>
* <li>Resets all settings.</li>
* <li>Changes the setting of Display.</li>
* <li>Changes the setting of Sharing.</li>
* </ul>
*/
public void testChangeAndReset() {
// Reset all settings.
EndToEndTestUtils.resetAllSettings(activityMyTracks, true);
// Change a setting of Map.
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.track_detail_stats_tab));
instrumentation.waitForIdleSync();
// Rotate on a sub setting page.
EndToEndTestUtils.rotateAllActivities();
EndToEndTestUtils.SOLO.waitForText(activityMyTracks
.getString(R.string.settings_stats_units_title));
ArrayList<CheckBox> displayCheckBoxs = EndToEndTestUtils.SOLO.getCurrentCheckBoxes();
boolean useMetric = displayCheckBoxs.get(0).isChecked();
EndToEndTestUtils.SOLO.clickOnCheckBox(0);
instrumentation.waitForIdleSync();
EndToEndTestUtils.SOLO.goBack();
// Change a setting of sharing.
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.settings_sharing));
assertTrue(EndToEndTestUtils.SOLO.waitForText(
activityMyTracks.getString(R.string.settings_sharing_allow_access), 1,
EndToEndTestUtils.NORMAL_WAIT_TIME));
ArrayList<CheckBox> sharingCheckBoxs = EndToEndTestUtils.SOLO.getCurrentCheckBoxes();
boolean newMapsPublic = sharingCheckBoxs.get(0).isChecked();
EndToEndTestUtils.SOLO.clickOnCheckBox(0);
instrumentation.waitForIdleSync();
assertTrue(EndToEndTestUtils.SOLO.waitForText(
activityMyTracks.getString(R.string.settings_sharing_allow_access), 1,
EndToEndTestUtils.NORMAL_WAIT_TIME));
assertEquals(!newMapsPublic, EndToEndTestUtils.SOLO.getCurrentCheckBoxes().get(0).isChecked());
EndToEndTestUtils.SOLO.goBack();
// Reset all settings.
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.settings_reset));
EndToEndTestUtils
.getButtonOnScreen(activityMyTracks.getString(R.string.generic_ok), true, true);
// Check settings.
// Add following scroll up for a bug of Robotium.
EndToEndTestUtils.SOLO.scrollUp();
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.track_detail_stats_tab));
assertTrue(EndToEndTestUtils.SOLO.waitForText(
activityMyTracks.getString(R.string.settings_stats_units_title), 1,
EndToEndTestUtils.LONG_WAIT_TIME));
displayCheckBoxs = EndToEndTestUtils.SOLO.getCurrentCheckBoxes();
assertEquals(useMetric, displayCheckBoxs.get(0).isChecked());
EndToEndTestUtils.SOLO.goBack();
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.settings_sharing));
EndToEndTestUtils.SOLO.waitForText(activityMyTracks
.getString(R.string.settings_sharing_allow_access));
sharingCheckBoxs = EndToEndTestUtils.SOLO.getCurrentCheckBoxes();
assertEquals(newMapsPublic, sharingCheckBoxs.get(0).isChecked());
}
/**
* Tests the change of preferred units.
*/
public void testChangePreferredUnits() {
EndToEndTestUtils.createTrackIfEmpty(5, false);
// Change it and verify it.
ChangePreferredUnits();
// Change it back and verify it.
ChangePreferredUnits();
}
/**
* Tests the change of stats settings during recording on chart view.
*/
public void testChangeStatsSettings_underRecording_chart() {
EndToEndTestUtils.startRecording();
// Test just change preferred units when display CHART tab.
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.track_detail_chart_tab));
EndToEndTestUtils.sendGps(3);
ChangeStatsSettings(true, false, false, false, false);
EndToEndTestUtils.sendGps(3, 3);
EndToEndTestUtils.stopRecording(true);
}
/**
* Tests the change of stats settings during recording on stats tab.
*/
public void testChangeStatsSettings_underRecording_stats() {
EndToEndTestUtils.startRecording();
// Test change preferred units and preferred rate when display STATS tab.
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.track_detail_stats_tab));
EndToEndTestUtils.sendGps(3);
ChangeStatsSettings(true, true, false, false, false);
EndToEndTestUtils.sendGps(3, 3);
EndToEndTestUtils.stopRecording(true);
}
/**
* Tests displaying elevation, grade and latitude and longitude information in
* Stats tab.
*/
public void testChangeStatsSettings_showExtraInfos() {
EndToEndTestUtils.createTrackIfEmpty(5, false);
EndToEndTestUtils.resetAllSettings(activityMyTracks, true);
ChangeStatsSettings(false, false, true, true, true);
instrumentation.waitForIdleSync();
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.track_detail_stats_tab));
assertTrue(EndToEndTestUtils.SOLO.waitForText(
activityMyTracks.getString(R.string.stats_min_elevation), 1,
EndToEndTestUtils.NORMAL_WAIT_TIME, true));
assertTrue(EndToEndTestUtils.SOLO.waitForText(activityMyTracks
.getString(R.string.stats_min_grade)));
assertTrue(EndToEndTestUtils.SOLO.waitForText(activityMyTracks
.getString(R.string.stats_latitude)));
}
/**
* Changes settings of preferred units and preferred rate.
*
* @param changeUnits is change the preferred unit
* @param changeRate is change the preferred rate
* @param changeElevation is change the elevation
* @param changeGrade is change the grade
* @param changeLatLong is change the latitude and longitude
*/
private void ChangeStatsSettings(boolean changeUnits, boolean changeRate,
boolean changeElevation, boolean changeGrade, boolean changeLatLong) {
EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_settings), true);
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.track_detail_stats_tab));
assertTrue(EndToEndTestUtils.SOLO.waitForText(activityMyTracks
.getString(R.string.settings_stats_units_title)));
// Change preferred units.
if (changeUnits) {
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks
.getString(R.string.settings_stats_units_title));
}
if (changeRate) {
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks
.getString(R.string.settings_stats_rate_title));
}
if (changeElevation) {
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.stats_elevation));
}
if (changeGrade) {
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.settings_stats_grade));
}
if (changeLatLong) {
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks
.getString(R.string.settings_stats_coordinate));
}
EndToEndTestUtils.SOLO.goBack();
EndToEndTestUtils.SOLO.goBack();
}
/**
* Changes PreferredUnits and verifies the change.
*/
private void ChangePreferredUnits() {
EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_settings), true);
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.track_detail_stats_tab));
assertTrue(EndToEndTestUtils.SOLO.waitForText(activityMyTracks
.getString(R.string.settings_stats_units_title)));
boolean isImperial = EndToEndTestUtils.findTextViewInView(activityMyTracks
.getString(R.string.settings_stats_units_imperial), EndToEndTestUtils.SOLO
.getCurrentListViews().get(0)) != null;
// Change preferred units.
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks
.getString(R.string.settings_stats_units_title));
isImperial = !isImperial;
EndToEndTestUtils.SOLO.goBack();
EndToEndTestUtils.SOLO.goBack();
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.track_detail_chart_tab));
instrumentation.waitForIdleSync();
ChartView chartView = EndToEndTestUtils.getChartView();
assertEquals(!isImperial, chartView.isMetricUnits());
}
/**
* Tests the backup.
*/
public void testBackup() {
// Delete all backup at first.
EndToEndTestUtils.deleteExportedFiles(EndToEndTestUtils.BACKUPS);
EndToEndTestUtils.createTrackIfEmpty(3, true);
// Write to SD card.
EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_settings), true);
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.settings_backup));
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.settings_backup_now));
assertTrue(EndToEndTestUtils.SOLO.waitForText(
activityMyTracks.getString(R.string.external_storage_save_success), 0,
EndToEndTestUtils.SUPER_LONG_WAIT_TIME));
instrumentation.waitForIdleSync();
// Delete all tracks.
EndToEndTestUtils.SOLO.goBack();
EndToEndTestUtils.SOLO.goBack();
EndToEndTestUtils.deleteAllTracks();
instrumentation.waitForIdleSync();
// Read from SD card.
EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_settings), true);
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.settings_backup));
EndToEndTestUtils.SOLO
.clickOnText(activityMyTracks.getString(R.string.settings_backup_restore));
EndToEndTestUtils
.getButtonOnScreen(activityMyTracks.getString(R.string.generic_ok), true, true);
assertTrue(EndToEndTestUtils.SOLO.waitForText(
activityMyTracks.getString(R.string.external_storage_import_success), 0,
EndToEndTestUtils.SUPER_LONG_WAIT_TIME));
// Check restore track.
assertTrue(EndToEndTestUtils.SOLO.searchText(EndToEndTestUtils.trackName));
}
/**
* Tests the setting of recording. This test changes the default name and
* activity of tracks, and the creates a new track to check it.
*/
public void testRecording() {
EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_settings), true);
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.settings_recording));
// Changes the setting of recording name.
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks
.getString(R.string.settings_recording_track_name_title));
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks
.getString(R.string.settings_recording_track_name_number_option));
// Changes the setting of default activity.
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks
.getString(R.string.settings_recording_default_activity_title));
EndToEndTestUtils.enterTextAvoidSoftKeyBoard(0, EndToEndTestUtils.activityType);
EndToEndTestUtils
.getButtonOnScreen(activityMyTracks.getString(R.string.generic_ok), true, true);
EndToEndTestUtils.SOLO.goBack();
EndToEndTestUtils.SOLO.goBack();
EndToEndTestUtils.startRecording();
instrumentation.waitForIdleSync();
EndToEndTestUtils.stopRecording(false);
instrumentation.waitForIdleSync();
assertTrue(EndToEndTestUtils.SOLO.searchText(activityMyTracks.getString(
R.string.track_name_format).split(" ")[0]));
assertTrue(EndToEndTestUtils.SOLO.searchText(EndToEndTestUtils.activityType));
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.generic_save));
}
/**
* Tests the setting of fixed track color settings.
*/
public void testTrackColorSettings_fixed() {
Context context = activityMyTracks.getApplicationContext();
EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_settings), true);
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.menu_map));
String errorString = "error";
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks
.getString(R.string.settings_map_track_color_mode));
instrumentation.waitForIdleSync();
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks
.getString(R.string.settings_map_track_color_mode_fixed));
EndToEndTestUtils.waitTextToDisappear(activityMyTracks
.getString(R.string.settings_map_track_color_mode_dynamic_value));
assertEquals(activityMyTracks.getString(R.string.settings_map_track_color_mode_fixed_value),
PreferencesUtils.getString(context, R.string.track_color_mode_key, errorString));
}
/**
* Tests the setting of dynamic track color settings.
*/
public void testTrackColorSettings_dynamic() {
Context context = activityMyTracks.getApplicationContext();
EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_settings), true);
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.menu_map));
String errorString = "error";
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks
.getString(R.string.settings_map_track_color_mode));
instrumentation.waitForIdleSync();
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks
.getString(R.string.settings_map_track_color_mode_dynamic));
EndToEndTestUtils.waitTextToDisappear(activityMyTracks
.getString(R.string.settings_map_track_color_mode_dynamic_value));
assertEquals(activityMyTracks.getString(R.string.settings_map_track_color_mode_dynamic_value),
PreferencesUtils.getString(context, R.string.track_color_mode_key, errorString));
}
/**
* Tests the setting of single track color settings.
*/
public void testTrackColorSettings_single() {
Context context = activityMyTracks.getApplicationContext();
EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_settings), true);
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.menu_map));
String errorString = "error";
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks
.getString(R.string.settings_map_track_color_mode));
instrumentation.waitForIdleSync();
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks
.getString(R.string.settings_map_track_color_mode_single));
EndToEndTestUtils.waitTextToDisappear(activityMyTracks
.getString(R.string.settings_map_track_color_mode_dynamic_value));
assertEquals(activityMyTracks.getString(R.string.settings_map_track_color_mode_single_value),
PreferencesUtils.getString(context, R.string.track_color_mode_key, errorString));
}
@Override
protected void tearDown() throws Exception {
EndToEndTestUtils.SOLO.finishOpenedActivities();
super.tearDown();
}
}
@@ -1,114 +0,0 @@
/*
* Copyright 2012 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.android.apps.mytracks.endtoendtest;
import com.google.android.apps.mytracks.TrackListActivity;
import com.google.android.apps.mytracks.fragments.MyTracksMapFragment;
import com.google.android.maps.mytracks.R;
import android.app.Instrumentation;
import android.test.ActivityInstrumentationTestCase2;
import android.widget.TextView;
/**
* Tests switching views and the menu list of each view.
*
* @author Youtao Liu
*/
public class ViewsTest extends ActivityInstrumentationTestCase2<TrackListActivity> {
private Instrumentation instrumentation;
private TrackListActivity activityMyTracks;
public ViewsTest() {
super(TrackListActivity.class);
}
@Override
protected void setUp() throws Exception {
super.setUp();
instrumentation = getInstrumentation();
activityMyTracks = getActivity();
EndToEndTestUtils.setupForAllTest(instrumentation, activityMyTracks);
}
/**
* Switches view from {@link MyTracksMapFragment} to @ ChartFragment} , then
* changes to @ StatsFragment} . Finally back to {@link MyTracksMapFragment}.
* And check some menus in these views. In MapFragment, the menu should
* contain satellite/map mode. In ChartFragment and StatsFragment, the menu
* should not contain satellite/map mode.
*/
public void testSwitchViewsAndMenusOfView() {
EndToEndTestUtils.createTrackIfEmpty(3, true);
EndToEndTestUtils.SOLO.scrollUp();
EndToEndTestUtils.SOLO.clickOnText(EndToEndTestUtils.trackName, 1, true);
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.track_detail_chart_tab));
EndToEndTestUtils.rotateAllActivities();
assertTrue(EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_settings),
false));
assertFalse(EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_map_layer),
false));
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.track_detail_stats_tab));
assertTrue(EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_settings),
false));
assertFalse(EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_map_layer),
false));
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.track_detail_map_tab));
EndToEndTestUtils.rotateAllActivities();
assertTrue(EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_settings),
false));
assertTrue(EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_map_layer),
false));
}
/**
* Tests the switch between satellite mode and map mode.
*/
public void testSatelliteAndMapView() {
instrumentation.waitForIdleSync();
EndToEndTestUtils.createTrackIfEmpty(1, false);
instrumentation.waitForIdleSync();
EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_map_layer), true);
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.menu_terrain));
instrumentation.waitForIdleSync();
EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_map_layer), true);
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.menu_satellite));
instrumentation.waitForIdleSync();
EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_map_layer), true);
// But in some languages only has one match(Such as French).
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.menu_map));
// The first match maybe a noise(The title of the radio dialog) for some
// language(Such as English), we should click the second one.
TextView text = EndToEndTestUtils.findTextViewByIndex(
activityMyTracks.getString(R.string.menu_map), 2);
if (text != null) {
EndToEndTestUtils.SOLO.clickOnView(text);
}
}
@Override
protected void tearDown() throws Exception {
EndToEndTestUtils.SOLO.finishOpenedActivities();
super.tearDown();
}
}
@@ -1,16 +0,0 @@
package com.google.android.apps.mytracks.endtoendtest.others;
public class BigTestUtils {
/**
* Set to false as default. True to run the test. Default to false since this
* test can take a long time.
*/
public static boolean runStressTest = true;
public static boolean runSensorTest = true;
protected static final String DISABLE_MESSAGE = "This test is disabled";
}
@@ -1,244 +0,0 @@
/*
* Copyright 2012 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.android.apps.mytracks.endtoendtest.others;
import com.google.android.apps.mytracks.TrackListActivity;
import com.google.android.apps.mytracks.endtoendtest.EndToEndTestUtils;
import com.google.android.maps.mytracks.R;
import android.app.Instrumentation;
import android.test.ActivityInstrumentationTestCase2;
import android.util.Log;
import android.widget.ListView;
import android.widget.TextView;
import java.util.ArrayList;
/**
* Tests connecting to sensors.
*
* @author Youtao Liu
*/
public class SensorTest extends ActivityInstrumentationTestCase2<TrackListActivity> {
public SensorTest() {
super(TrackListActivity.class);
}
private Instrumentation instrumentation;
private TrackListActivity trackListActivity;
private boolean runTest = false;
private static final String ZEPHYR_NAME = "HXM";
private static final String POLAR_NAME = "Polar";
@Override
protected void setUp() throws Exception {
runTest = BigTestUtils.runSensorTest;
super.setUp();
if (!runTest) {
return;
}
instrumentation = getInstrumentation();
trackListActivity = getActivity();
EndToEndTestUtils.setupForAllTest(instrumentation, trackListActivity);
}
/**
* Tests connecting to a Zephyr Bluetooth sensor while not recording. Before this test, a Zephyr
* sensor must be paired with the device.
*/
public void testConnectZephyrBluetoothSensor_notRecording() {
if (!runTest) {
Log.i(EndToEndTestUtils.LOG_TAG, BigTestUtils.DISABLE_MESSAGE);
return;
}
bluetoothSensorTest(R.string.settings_sensor_type_zephyr, ZEPHYR_NAME, false);
}
/**
* Tests connecting to a Zephyr Bluetooth sensor while under recording. Before this test, a Zephyr
* sensor must be paired with the device.
*/
public void testConnectZephyrBluetoothSensor_underRecording() {
if (!runTest) {
Log.i(EndToEndTestUtils.LOG_TAG, BigTestUtils.DISABLE_MESSAGE);
return;
}
bluetoothSensorTest(R.string.settings_sensor_type_zephyr, ZEPHYR_NAME, true);
}
/**
* Tests connecting to a Polar Bluetooth sensor while not recording. Before this test, a Polar
* sensor must be paired with the device.
*/
public void testConnectPolarBluetoothSensor_notRecording() {
if (!runTest) {
Log.i(EndToEndTestUtils.LOG_TAG, BigTestUtils.DISABLE_MESSAGE);
return;
}
bluetoothSensorTest(R.string.settings_sensor_type_polar, POLAR_NAME, false);
}
/**
* Tests connecting to a Polar Bluetooth sensor while under recording. Before this test, a Polar
* sensor must be paired with the device.
*/
public void testConnectPolarBluetoothSensor_underRecording() {
if (!runTest) {
Log.i(EndToEndTestUtils.LOG_TAG, BigTestUtils.DISABLE_MESSAGE);
return;
}
bluetoothSensorTest(R.string.settings_sensor_type_polar, POLAR_NAME, true);
}
/**
* Set the paired sensor.
*
* @param sensorTypeStringId the string id of paired sensors type
* @param nameString part of the sensor name string which can distinguish
* different Bluetooth sensors
* @param isUnderRecording true means test under recording
*/
private void bluetoothSensorTest(int sensorTypeStringId, String nameString,
boolean isUnderRecording) {
EndToEndTestUtils.findMenuItem(trackListActivity.getString(R.string.menu_settings), true);
EndToEndTestUtils.SOLO.clickOnText(trackListActivity.getString(R.string.settings_sensor));
EndToEndTestUtils.SOLO.clickOnText(trackListActivity.getString(R.string.settings_sensor_type));
EndToEndTestUtils.SOLO.clickOnText(trackListActivity.getString(sensorTypeStringId));
checkPairedSensorsNumber(nameString);
// Set the paired sensor.
EndToEndTestUtils.SOLO.clickOnText(nameString);
EndToEndTestUtils.SOLO.goBack();
EndToEndTestUtils.SOLO.goBack();
if (isUnderRecording) {
assertTrue(checkSensorsStatus_underRecording());
} else {
assertTrue(checkSensorsStatus_notRecording());
}
}
/**
* Checks the number of paired sensors.
*/
private void checkPairedSensorsNumber(String nameString) {
EndToEndTestUtils.SOLO.clickOnText(trackListActivity
.getString(R.string.settings_sensor_bluetooth_sensor));
instrumentation.waitForIdleSync();
ArrayList<ListView> allListViews = EndToEndTestUtils.SOLO.getCurrentListViews();
int number = allListViews.get(0).getCount();
if (number > 0
&& EndToEndTestUtils.SOLO.waitForText(nameString, 1, EndToEndTestUtils.SHORT_WAIT_TIME)) {
return;
}
Log.i(EndToEndTestUtils.LOG_TAG, "No sensor is paried");
fail("No bluetooth sensor is paired. Please pair at Settings->Bluetooth before running the test.");
}
/**
* Tests connecting to a cadence ANT+ sensor.
*/
public void testConnectANTSensor_Cadence() {
if (!runTest) {
Log.i(EndToEndTestUtils.LOG_TAG, BigTestUtils.DISABLE_MESSAGE);
return;
}
useANTSeonsor();
assertTrue(checkSensorsStatus_notRecording());
checkANTSensorsStatus(R.id.sensor_state_cadence);
}
/**
* Tests connecting to cadence and heart rate ANT+ sensors at the same time.
*/
public void testConnectTwoANTSensors() {
if (!runTest) {
Log.i(EndToEndTestUtils.LOG_TAG, BigTestUtils.DISABLE_MESSAGE);
return;
}
useANTSeonsor();
assertTrue(checkSensorsStatus_notRecording());
checkANTSensorsStatus(R.id.sensor_state_cadence);
checkANTSensorsStatus(R.id.sensor_state_heart_rate);
}
/**
* Sets the setting to use ANT+ sensor
*/
private void useANTSeonsor() {
EndToEndTestUtils.findMenuItem(trackListActivity.getString(R.string.menu_settings), true);
EndToEndTestUtils.SOLO.clickOnText(trackListActivity.getString(R.string.settings_sensor));
EndToEndTestUtils.SOLO.clickOnText(trackListActivity.getString(R.string.settings_sensor_type));
EndToEndTestUtils.SOLO.clickOnText(trackListActivity
.getString(R.string.settings_sensor_type_ant));
EndToEndTestUtils.SOLO.goBack();
EndToEndTestUtils.SOLO.goBack();
}
/**
* Checks whether the ANT+ sensor is connected with MyTracks.
*
* @param viewID the id to check which is not equal with None
*/
private void checkANTSensorsStatus(int viewID) {
TextView sensorValueText = ((TextView) EndToEndTestUtils.SOLO.getCurrentActivity()
.findViewById(viewID));
assertNotNull(sensorValueText);
String realValue = sensorValueText.getText().toString();
String noneValue = trackListActivity.getString(R.string.settings_sensor_type_none);
assertNotSame(realValue, noneValue);
}
/**
* Checks whether the sensor is connected with MyTracks during recording.
*
* @return true means the sensor is connected with MyTracks
*/
private boolean checkSensorsStatus_underRecording() {
EndToEndTestUtils.instrumentation.waitForIdleSync();
EndToEndTestUtils.startRecording();
EndToEndTestUtils.findMenuItem(trackListActivity.getString(R.string.menu_sensor_state), true);
boolean result = EndToEndTestUtils.SOLO.waitForText(
trackListActivity.getString(R.string.sensor_state_connected), 1,
EndToEndTestUtils.LONG_WAIT_TIME);
EndToEndTestUtils.stopRecording(true);
return result;
}
/**
* Checks whether the sensor is connected with MyTracks while not under recording.
*
* @return true means the sensor is connected with MyTracks
*/
private boolean checkSensorsStatus_notRecording() {
EndToEndTestUtils.instrumentation.waitForIdleSync();
EndToEndTestUtils.createTrackIfEmpty(0, false);
EndToEndTestUtils.findMenuItem(trackListActivity.getString(R.string.menu_sensor_state), true);
return EndToEndTestUtils.SOLO.waitForText(
trackListActivity.getString(R.string.sensor_state_connected), 1,
EndToEndTestUtils.LONG_WAIT_TIME);
}
@Override
protected void tearDown() throws Exception {
if (!runTest) {
return;
}
EndToEndTestUtils.SOLO.finishOpenedActivities();
super.tearDown();
}
}
@@ -1,172 +0,0 @@
/*
* Copyright 2012 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.android.apps.mytracks.endtoendtest.others;
import com.google.android.apps.mytracks.TrackListActivity;
import com.google.android.apps.mytracks.endtoendtest.EndToEndTestUtils;
import com.google.android.maps.mytracks.R;
import android.app.Instrumentation;
import android.test.ActivityInstrumentationTestCase2;
import android.util.Log;
/**
* Stress test of MyTracks.
*
* @author Youtao Liu
*/
public class StressTest extends ActivityInstrumentationTestCase2<TrackListActivity> {
private static final int TEST_DURATION_IN_MILLISECONDS = 30 * 60 * 1000;
private static final int MAX_TRACK_NUMBER = 30;
private boolean runTest = false;
private long startTime = 0;
private int numberOfTracks;
public StressTest() {
super(TrackListActivity.class);
}
private Instrumentation instrumentation;
private TrackListActivity trackListActivity;
@Override
protected void setUp() throws Exception {
runTest = BigTestUtils.runStressTest;
super.setUp();
if (!runTest) {
return;
}
instrumentation = getInstrumentation();
trackListActivity = getActivity();
EndToEndTestUtils.setupForAllTest(instrumentation, trackListActivity);
startTime = System.currentTimeMillis();
}
/**
* Records tracks and deletes them when there are more than
* {@link #MAX_TRACK_NUMBER} tracks. Keeps sending different GPS locations in
* each track, making it closer to the real stress.
*/
public void testRecordAndDeleteTracks() {
if (!runTest) {
Log.i(EndToEndTestUtils.LOG_TAG, BigTestUtils.DISABLE_MESSAGE);
return;
}
for (int i = 0; (System.currentTimeMillis() - startTime) < TEST_DURATION_IN_MILLISECONDS; i++) {
EndToEndTestUtils.startRecording();
// Points in a tracks keep increasing.
EndToEndTestUtils.sendGps(i * 10, 0, 10);
EndToEndTestUtils.stopRecording(true);
EndToEndTestUtils.SOLO.goBack();
EndToEndTestUtils.instrumentation.waitForIdleSync();
numberOfTracks = EndToEndTestUtils.SOLO.getCurrentListViews().get(0).getCount();
if (numberOfTracks > MAX_TRACK_NUMBER) {
EndToEndTestUtils.deleteAllTracks();
}
logStatus(i);
}
}
/**
* Rotates screen when display map view. Keeps sending different GPS locations
* in each track, making it closer to the real stress.
*/
public void testRotateMapViewInTrackDetailActivity() {
if (!runTest) {
Log.i(EndToEndTestUtils.LOG_TAG, BigTestUtils.DISABLE_MESSAGE);
return;
}
EndToEndTestUtils.startRecording();
for (int i = 0; (System.currentTimeMillis() - startTime) < TEST_DURATION_IN_MILLISECONDS; i++) {
EndToEndTestUtils.sendGps(10, i * 10);
EndToEndTestUtils.rotateCurrentActivity();
Log.i(EndToEndTestUtils.LOG_TAG, String.format("Totate %d times in %d minutes!", i,
(System.currentTimeMillis() - startTime) / 1000 / 60));
}
}
/**
* Switches view between MAP, CHART and STAT.
*/
public void testSwitchTabs() {
if (!runTest) {
Log.i(EndToEndTestUtils.LOG_TAG, BigTestUtils.DISABLE_MESSAGE);
return;
}
EndToEndTestUtils.startRecording();
int i = 0;
while ((System.currentTimeMillis() - startTime) < TEST_DURATION_IN_MILLISECONDS) {
EndToEndTestUtils.SOLO
.clickOnText(trackListActivity.getString(R.string.track_detail_map_tab));
instrumentation.waitForIdleSync();
EndToEndTestUtils.SOLO.clickOnText(trackListActivity
.getString(R.string.track_detail_chart_tab));
instrumentation.waitForIdleSync();
EndToEndTestUtils.SOLO.clickOnText(trackListActivity
.getString(R.string.track_detail_stats_tab));
instrumentation.waitForIdleSync();
logStatus(++i);
}
EndToEndTestUtils.stopRecording(true);
}
/**
* Switches view between MAP, CHART and STAT. And create way points, pause and
* resume the track during recording.
*/
public void testSwitchTabs_wayPoints() {
if (!runTest) {
Log.i(EndToEndTestUtils.LOG_TAG, BigTestUtils.DISABLE_MESSAGE);
return;
}
EndToEndTestUtils.startRecording();
int i = 0;
while ((System.currentTimeMillis() - startTime) < TEST_DURATION_IN_MILLISECONDS) {
// Create one way points.
EndToEndTestUtils.sendGps(10, 10 * i);
EndToEndTestUtils.createWaypoint(i);
EndToEndTestUtils.pauseRecording();
EndToEndTestUtils.SOLO
.clickOnText(trackListActivity.getString(R.string.track_detail_map_tab));
instrumentation.waitForIdleSync();
EndToEndTestUtils.SOLO.clickOnText(trackListActivity
.getString(R.string.track_detail_chart_tab));
instrumentation.waitForIdleSync();
EndToEndTestUtils.SOLO.clickOnText(trackListActivity
.getString(R.string.track_detail_stats_tab));
instrumentation.waitForIdleSync();
EndToEndTestUtils.resumeRecording();
logStatus(++i);
}
EndToEndTestUtils.stopRecording(true);
}
/**
* Logs status.
*
* @param times the number of times this test has been run
*/
private void logStatus(int times) {
int minutes = (int) (TEST_DURATION_IN_MILLISECONDS - (System.currentTimeMillis() - startTime)) / 60 / 1000;
Log.i(EndToEndTestUtils.LOG_TAG, String.format(
"This test has run %d times and will be finished in %d minutes!", times, minutes));
Log.i(EndToEndTestUtils.LOG_TAG, String.format("There are %d tracks!", numberOfTracks));
}
}