calabash-android 0.2.11 → 0.2.12
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES.txt +6 -0
- data/features-skeleton/support/app_installation_hooks.rb +11 -3
- data/features-skeleton/support/app_life_cycle_hooks.rb +9 -0
- data/features-skeleton/support/hooks.rb +18 -2
- data/lib/calabash-android/operations.rb +1 -1
- data/lib/calabash-android/steps/assert_steps.rb +12 -0
- data/lib/calabash-android/steps/list_steps.rb +40 -0
- data/lib/calabash-android/steps/map_steps.rb +61 -0
- data/lib/calabash-android/steps/navigation_steps.rb +10 -1
- data/lib/calabash-android/steps/progress_steps.rb +5 -0
- data/lib/calabash-android/version.rb +2 -2
- data/test-server/AndroidManifest.xml +5 -5
- data/test-server/build.xml +4 -0
- data/test-server/instrumentation-backend/.gitignore +1 -0
- data/test-server/instrumentation-backend/AndroidManifest.xml +4 -3
- data/test-server/instrumentation-backend/project.properties +1 -1
- data/test-server/instrumentation-backend/src/com/jayway/android/robotium/solo/MapViewUtils.java +328 -0
- data/test-server/instrumentation-backend/src/com/jayway/android/robotium/solo/SoloEnhanced.java +97 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/InstrumentationBackend.java +3 -3
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/TestHelpers.java +51 -1
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/list/GetListItemProperties.java +195 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/list/GetListItemText.java +136 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/map/GetMapBounds.java +27 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/map/GetMapCenter.java +27 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/map/GetMapMarker.java +31 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/map/GetMapMarkers.java +48 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/map/GetMapZoom.java +19 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/map/PanMapTo.java +23 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/map/SetMapCenter.java +23 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/map/SetMapZoom.java +34 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/map/TapAwayFromMarkers.java +28 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/map/TapMapMarker.java +29 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/spinner/GetSelectedSpinnerItemText.java +36 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/text/AssertGridViewContainsNoDuplicates.java +72 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/text/GetTextById.java +42 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/view/AssertViewProperty.java +141 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/view/ClickOnViewById.java +1 -8
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/view/GetActivityName.java +32 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/view/GetViewProperty.java +107 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/view/HasView.java +31 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/view/Press.java +1 -1
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/view/SelectTab.java +110 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/wait/WaitForScreen.java +10 -6
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/wait/WaitForTab.java +108 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/{view → wait}/WaitForView.java +1 -1
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/{view → wait}/WaitForViewById.java +21 -11
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/QueryHelper.java +3 -3
- metadata +102 -88
data/test-server/instrumentation-backend/src/com/jayway/android/robotium/solo/SoloEnhanced.java
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
package com.jayway.android.robotium.solo;
|
2
|
+
|
3
|
+
import java.util.List;
|
4
|
+
|
5
|
+
import android.app.Activity;
|
6
|
+
import android.app.Instrumentation;
|
7
|
+
|
8
|
+
public class SoloEnhanced extends Solo {
|
9
|
+
// private Pincher pincher;
|
10
|
+
private MapViewUtils mapViewUtils;
|
11
|
+
|
12
|
+
public SoloEnhanced(Instrumentation instrumentation, Activity activity) {
|
13
|
+
super(instrumentation, activity);
|
14
|
+
this.mapViewUtils = new MapViewUtils(instrumentation, viewFetcher, sleeper, waiter);
|
15
|
+
// this.pincher = new Pincher(instrumentation, viewFetcher);
|
16
|
+
}
|
17
|
+
|
18
|
+
public void setMapCenter( double lat, double lon ) {
|
19
|
+
mapViewUtils.setCenter(lat, lon);
|
20
|
+
}
|
21
|
+
|
22
|
+
/** @return {lat,lon} */
|
23
|
+
public double[] getMapCenter() {
|
24
|
+
return mapViewUtils.getMapCenter();
|
25
|
+
}
|
26
|
+
|
27
|
+
public void panMapTo( double lat, double lon ) {
|
28
|
+
mapViewUtils.panTo(lat, lon);
|
29
|
+
}
|
30
|
+
|
31
|
+
public boolean zoomInOnMap() {
|
32
|
+
return mapViewUtils.zoomIn();
|
33
|
+
}
|
34
|
+
|
35
|
+
public boolean zoomOutOnMap() {
|
36
|
+
return mapViewUtils.zoomOut();
|
37
|
+
}
|
38
|
+
|
39
|
+
public int setMapZoom( int zoomLevel ) {
|
40
|
+
return mapViewUtils.setZoom(zoomLevel);
|
41
|
+
}
|
42
|
+
|
43
|
+
public int getMapZoom() {
|
44
|
+
return mapViewUtils.getZoom();
|
45
|
+
}
|
46
|
+
|
47
|
+
public List<String> getMapMarkerItems() {
|
48
|
+
return mapViewUtils.getMarkerItems();
|
49
|
+
}
|
50
|
+
|
51
|
+
public String getMapMarkerItem( String title ) {
|
52
|
+
return mapViewUtils.getMarkerItem( title );
|
53
|
+
}
|
54
|
+
|
55
|
+
/**
|
56
|
+
* @param title
|
57
|
+
* @param timeout in ms
|
58
|
+
* @return
|
59
|
+
*/
|
60
|
+
public boolean tapMapMarkerItem( String title, long timeout ) {
|
61
|
+
return mapViewUtils.tapMarkerItem( title, timeout );
|
62
|
+
}
|
63
|
+
|
64
|
+
public boolean tapMapAwayFromMarkers( int step ) {
|
65
|
+
return mapViewUtils.tapAwayFromMarkerItems( step );
|
66
|
+
}
|
67
|
+
|
68
|
+
/**
|
69
|
+
* @return [top, right, bottom, left] in decimal degrees
|
70
|
+
*/
|
71
|
+
public List<String> getMapBounds() {
|
72
|
+
return mapViewUtils.getBounds();
|
73
|
+
}
|
74
|
+
|
75
|
+
// /**
|
76
|
+
// * Sorry, doesn't work yet
|
77
|
+
// * @param togetherOrApart - {@link Pincher#TOGETHER} or {@link Pincher#APART}
|
78
|
+
// */
|
79
|
+
// public void pinch(int togetherOrApart) {
|
80
|
+
// switch( togetherOrApart ) {
|
81
|
+
// case Pincher.TOGETHER: pincher.pinch(Pincher.Direction.TOGETHER); break;
|
82
|
+
// case Pincher.APART: pincher.pinch(Pincher.Direction.APART); break;
|
83
|
+
// }
|
84
|
+
// }
|
85
|
+
//
|
86
|
+
// /**
|
87
|
+
// * Sorry, doesn't work yet
|
88
|
+
// * @param togetherOrApart - {@link Pincher#TOGETHER} or {@link Pincher#APART}
|
89
|
+
// * @param view
|
90
|
+
// */
|
91
|
+
// public void pinch(int togetherOrApart, View view) {
|
92
|
+
// switch( togetherOrApart ) {
|
93
|
+
// case Pincher.TOGETHER: pincher.pinch(Pincher.Direction.TOGETHER, view); break;
|
94
|
+
// case Pincher.APART: pincher.pinch(Pincher.Direction.APART, view); break;
|
95
|
+
// }
|
96
|
+
// }
|
97
|
+
}
|
@@ -6,7 +6,7 @@ import android.app.Instrumentation;
|
|
6
6
|
import android.test.ActivityInstrumentationTestCase2;
|
7
7
|
import android.util.Log;
|
8
8
|
|
9
|
-
import com.jayway.android.robotium.solo.
|
9
|
+
import com.jayway.android.robotium.solo.SoloEnhanced;
|
10
10
|
|
11
11
|
public class InstrumentationBackend extends ActivityInstrumentationTestCase2 {
|
12
12
|
public static final String TARGET_PACKAGE = "#ACTIVITY_PACKAGE#"; //Set from Ant at compile time
|
@@ -15,7 +15,7 @@ public class InstrumentationBackend extends ActivityInstrumentationTestCase2 {
|
|
15
15
|
private static final String TAG = "InstrumentationBackend";
|
16
16
|
|
17
17
|
public static Instrumentation instrumentation;
|
18
|
-
public static
|
18
|
+
public static SoloEnhanced solo;
|
19
19
|
public static Actions actions;
|
20
20
|
|
21
21
|
private static Class getActivityClass() {
|
@@ -34,7 +34,7 @@ public class InstrumentationBackend extends ActivityInstrumentationTestCase2 {
|
|
34
34
|
protected void setUp() throws Exception {
|
35
35
|
super.setUp();
|
36
36
|
|
37
|
-
solo = new
|
37
|
+
solo = new SoloEnhanced(getInstrumentation(), this.getActivity());
|
38
38
|
actions = new Actions(getInstrumentation(), this);
|
39
39
|
instrumentation = getInstrumentation();
|
40
40
|
TestHelpers.loadIds(instrumentation.getContext());
|
data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/TestHelpers.java
CHANGED
@@ -12,6 +12,8 @@ import java.util.HashMap;
|
|
12
12
|
import java.util.Map;
|
13
13
|
|
14
14
|
import android.content.Context;
|
15
|
+
import android.content.res.Resources.NotFoundException;
|
16
|
+
import android.graphics.drawable.Drawable;
|
15
17
|
import android.view.View;
|
16
18
|
import android.widget.TextView;
|
17
19
|
|
@@ -69,6 +71,21 @@ public class TestHelpers {
|
|
69
71
|
return null;
|
70
72
|
}
|
71
73
|
|
74
|
+
@SuppressWarnings("unchecked")
|
75
|
+
public static <ViewType extends View> ViewType getViewById(String resName, Class<? extends View> expectedViewType) {
|
76
|
+
final View theView = getViewById(resName);
|
77
|
+
|
78
|
+
if (null == theView) {
|
79
|
+
return null;
|
80
|
+
}
|
81
|
+
|
82
|
+
if (!expectedViewType.isInstance(theView)) {
|
83
|
+
throw new RuntimeException(String.format("getViewById: Expected to find a View of type %s but found one of type %s", expectedViewType.getClass().getName(), theView.getClass().getName()));
|
84
|
+
}
|
85
|
+
|
86
|
+
return (ViewType) theView;
|
87
|
+
}
|
88
|
+
|
72
89
|
public static View getViewById(String resName) {
|
73
90
|
Integer intID = resourceNamesToIds.get(resName);
|
74
91
|
System.out.println("getViewById: Looking for view " + resName + " as id " + intID);
|
@@ -76,7 +93,7 @@ public class TestHelpers {
|
|
76
93
|
throw new RuntimeException("getViewById: Looking for view " + resName + " which does not have an id");
|
77
94
|
}
|
78
95
|
int id = intID.intValue();
|
79
|
-
View view = InstrumentationBackend.solo.
|
96
|
+
View view = InstrumentationBackend.solo.getView(id);
|
80
97
|
if (view != null) {
|
81
98
|
if (id == view.getId()) {
|
82
99
|
System.out.println("Did find view " + resName + ".");
|
@@ -87,6 +104,39 @@ public class TestHelpers {
|
|
87
104
|
System.out.println("Did not find view " + resName);
|
88
105
|
return view;
|
89
106
|
}
|
107
|
+
|
108
|
+
public static Drawable getDrawableById(String resName) {
|
109
|
+
int id;
|
110
|
+
// This would probably work too...
|
111
|
+
if( true ) {
|
112
|
+
try {
|
113
|
+
// if( resName.startsWith("drawable/") == false ) {
|
114
|
+
// resName = "drawable/" + resName;
|
115
|
+
// }
|
116
|
+
// TypedValue outValue = new TypedValue();
|
117
|
+
// InstrumentationBackend.solo.getCurrentActivity().getResources().getValue( resName, outValue, false );
|
118
|
+
// id = outValue.resourceId;
|
119
|
+
id = InstrumentationBackend.solo.getCurrentActivity().getResources().getIdentifier( resName, "drawable", InstrumentationBackend.solo.getCurrentActivity().getPackageName() );
|
120
|
+
} catch( NotFoundException e ) {
|
121
|
+
throw new RuntimeException("getDrawableById: Looking for drawable " + resName + " but was not found");
|
122
|
+
}
|
123
|
+
} else {
|
124
|
+
Integer intID = resourceNamesToIds.get(resName);
|
125
|
+
System.out.println("getDrawableById: Looking for drawable " + resName + " as id " + intID);
|
126
|
+
if (intID == null) {
|
127
|
+
throw new RuntimeException("getDrawableById: Looking for drawable " + resName + " which does not have an id");
|
128
|
+
}
|
129
|
+
id = intID.intValue();
|
130
|
+
}
|
131
|
+
Drawable drawable = InstrumentationBackend.solo.getCurrentActivity().getResources().getDrawable(id);
|
132
|
+
if (drawable != null) {
|
133
|
+
System.out.println("Did find drawable " + resName + ": " + drawable);
|
134
|
+
return drawable;
|
135
|
+
} else {
|
136
|
+
System.out.println("Did not find drawable " + resName);
|
137
|
+
return drawable;
|
138
|
+
}
|
139
|
+
}
|
90
140
|
|
91
141
|
public static int[] parseTime(String timeString) {
|
92
142
|
String[] splitTimeString = timeString.split(":");
|
@@ -0,0 +1,195 @@
|
|
1
|
+
package sh.calaba.instrumentationbackend.actions.list;
|
2
|
+
|
3
|
+
import java.lang.reflect.Method;
|
4
|
+
import java.util.ArrayList;
|
5
|
+
|
6
|
+
import sh.calaba.instrumentationbackend.InstrumentationBackend;
|
7
|
+
import sh.calaba.instrumentationbackend.Result;
|
8
|
+
import sh.calaba.instrumentationbackend.actions.Action;
|
9
|
+
import android.graphics.drawable.ColorDrawable;
|
10
|
+
import android.graphics.drawable.Drawable;
|
11
|
+
import android.view.View;
|
12
|
+
import android.view.ViewGroup;
|
13
|
+
import android.widget.ListView;
|
14
|
+
import android.widget.TableRow;
|
15
|
+
import android.widget.TextView;
|
16
|
+
|
17
|
+
/**
|
18
|
+
* args:
|
19
|
+
* <ul>
|
20
|
+
* <li>1-based list index (first list is used if not specified)</li>
|
21
|
+
* <li>1-based row index (returns all rows if <=0 or not specified)</li>
|
22
|
+
* </ul>
|
23
|
+
*
|
24
|
+
* eg: (all items of 1st list) <code>performAction( 'get_list_item_properties' )</code>
|
25
|
+
* eg: (all items of 2nd list) <code>performAction( 'get_list_item_properties', '2' )</code>
|
26
|
+
* eg: (1st item of 2nd list) <code>performAction( 'get_list_item_properties', '2' , '1' )</code>
|
27
|
+
*
|
28
|
+
* @return <code>bonusInformation</code> contain an array of Strings, one for each row in the list (or only for the specified row):
|
29
|
+
* eg: {[{"id":"title", "text":"My Title", "compoundDrawables":["left"]}, {"id":"subtitle", "text":"Another text field for the same list item"}]}
|
30
|
+
*
|
31
|
+
*
|
32
|
+
* In ruby, we can then parse the response:
|
33
|
+
* <pre>
|
34
|
+
* response_table = result['bonusInformation']
|
35
|
+
* response_table.each_with_index do | row_data, index |
|
36
|
+
* row_data = JSON.parse( row_data )
|
37
|
+
* response_table[index] = row_data
|
38
|
+
* end
|
39
|
+
* </pre>
|
40
|
+
*
|
41
|
+
* @author Nicholas Albion
|
42
|
+
*/
|
43
|
+
public class GetListItemProperties implements Action {
|
44
|
+
|
45
|
+
@Override
|
46
|
+
public Result execute(String... args) {
|
47
|
+
int listIndex;
|
48
|
+
int rowIndex = -1;
|
49
|
+
|
50
|
+
if( args.length == 0 ) {
|
51
|
+
listIndex = 0;
|
52
|
+
} else {
|
53
|
+
if( args.length > 1 ) {
|
54
|
+
rowIndex = (Integer.parseInt(args[1]) - 1);
|
55
|
+
}
|
56
|
+
listIndex = (Integer.parseInt(args[0]) - 1);
|
57
|
+
}
|
58
|
+
|
59
|
+
|
60
|
+
ArrayList<ListView> listViews = InstrumentationBackend.solo.getCurrentListViews();
|
61
|
+
if( listViews == null || listViews.size() <= listIndex ) {
|
62
|
+
return new Result(false, "Could not find list #" + (listIndex + 1));
|
63
|
+
}
|
64
|
+
|
65
|
+
ListView list = listViews.get(listIndex);
|
66
|
+
Result result = new Result(true);
|
67
|
+
|
68
|
+
if( rowIndex < 0 ) {
|
69
|
+
int count = list.getChildCount();
|
70
|
+
for( int i = 0; i < count; i++ ) {
|
71
|
+
result.addBonusInformation( getListItemString( list.getChildAt(i) ) );
|
72
|
+
}
|
73
|
+
} else {
|
74
|
+
result.addBonusInformation( getListItemString( list.getChildAt(rowIndex) ) );
|
75
|
+
}
|
76
|
+
|
77
|
+
return result;
|
78
|
+
}
|
79
|
+
|
80
|
+
/**
|
81
|
+
* @return <code>bonusInformation</code> contain an array of Strings, one for each row in the list (or only for the specified row):
|
82
|
+
* eg: {[{"id":"title", "text":"My Title", "compoundDrawables":{"left":"drawable_id"}}, {"id":"subtitle", "text":"Another text field for the same list item"}]}
|
83
|
+
*/
|
84
|
+
private String getListItemString( View row ) {
|
85
|
+
StringBuilder json = new StringBuilder("{");
|
86
|
+
|
87
|
+
if( row instanceof TextView ) {
|
88
|
+
addViewInfo( json, (TextView)row );
|
89
|
+
} else if( row instanceof ViewGroup ) {
|
90
|
+
addViewInfo( json, (ViewGroup)row );
|
91
|
+
}
|
92
|
+
|
93
|
+
json.deleteCharAt( json.length() - 1 ); // remove the last comma
|
94
|
+
json.append('}');
|
95
|
+
return json.toString();
|
96
|
+
}
|
97
|
+
|
98
|
+
private void addViewInfo( StringBuilder json, TextView view ) {
|
99
|
+
int resId = view.getId();
|
100
|
+
String resIdName = view.getResources().getResourceEntryName(resId);
|
101
|
+
|
102
|
+
json.append("\"id\":\"").append(resIdName).append("\", \"text:\"").append( ((TextView)view).getText() ).append("\"");
|
103
|
+
|
104
|
+
json.append(", \"color\":").append( view.getCurrentTextColor() );
|
105
|
+
Drawable background = view.getBackground();
|
106
|
+
if( background instanceof ColorDrawable ) {
|
107
|
+
try {
|
108
|
+
// As pointed out by kbielenberg, ColorDrawable.getColor() was only added in level 11/Android 3/Honeycomb
|
109
|
+
Method getColor = ColorDrawable.class.getMethod("getColor");
|
110
|
+
Integer color = (Integer)getColor.invoke(background);
|
111
|
+
json.append(", \"background\":").append( color );
|
112
|
+
} catch (Exception e) {}
|
113
|
+
}
|
114
|
+
|
115
|
+
StringBuilder compoundStr = new StringBuilder();
|
116
|
+
Drawable[] compoundDrawables = view.getCompoundDrawables(); // left, top, right, and bottom
|
117
|
+
if( compoundDrawables[0] != null ) {
|
118
|
+
compoundStr.append("\"left\"");
|
119
|
+
}
|
120
|
+
if( compoundDrawables[1] != null ) {
|
121
|
+
if( compoundStr.length() != 0 ) {
|
122
|
+
compoundStr.append(',');
|
123
|
+
}
|
124
|
+
compoundStr.append("\"top\"");
|
125
|
+
}
|
126
|
+
if( compoundDrawables[2] != null ) {
|
127
|
+
if( compoundStr.length() != 0 ) {
|
128
|
+
compoundStr.append(',');
|
129
|
+
}
|
130
|
+
compoundStr.append("\"right\"");
|
131
|
+
}
|
132
|
+
if( compoundDrawables[3] != null ) {
|
133
|
+
if( compoundStr.length() != 0 ) {
|
134
|
+
compoundStr.append(',');
|
135
|
+
}
|
136
|
+
compoundStr.append("\"bottom\"");
|
137
|
+
}
|
138
|
+
if( compoundStr.length() != 0 ) {
|
139
|
+
json.append(", \"compoundDrawables\":[").append(compoundStr).append(']');
|
140
|
+
}
|
141
|
+
}
|
142
|
+
|
143
|
+
private void addViewInfo( StringBuilder json, TableRow tableRow ) {
|
144
|
+
json.append("\"cells\":[");
|
145
|
+
|
146
|
+
int count = tableRow.getVirtualChildCount();
|
147
|
+
for( int i = 0; i < count; i++ ) {
|
148
|
+
if( i != 0 ) {
|
149
|
+
json.append(", ");
|
150
|
+
}
|
151
|
+
json.append("{\"column\":").append(i).append(", ");
|
152
|
+
|
153
|
+
View view = tableRow.getVirtualChildAt(i);
|
154
|
+
if( view instanceof TextView ) {
|
155
|
+
addViewInfo( json, (TextView)view );
|
156
|
+
} else if( view instanceof ViewGroup ) {
|
157
|
+
addViewInfo( json, (ViewGroup)view );
|
158
|
+
}
|
159
|
+
|
160
|
+
json.append('}');
|
161
|
+
}
|
162
|
+
|
163
|
+
json.append(']');
|
164
|
+
}
|
165
|
+
|
166
|
+
private void addViewInfo( StringBuilder json, ViewGroup viewGroup ) {
|
167
|
+
json.append("\"children\":[");
|
168
|
+
|
169
|
+
int count = viewGroup.getChildCount();
|
170
|
+
for( int i = 0; i < count; i++ ) {
|
171
|
+
if( i != 0 ) {
|
172
|
+
json.append(", ");
|
173
|
+
}
|
174
|
+
json.append('{');
|
175
|
+
|
176
|
+
View view = viewGroup.getChildAt(i);
|
177
|
+
if( view instanceof TextView ) {
|
178
|
+
addViewInfo( json, (TextView)view );
|
179
|
+
} else if( view instanceof TableRow ) {
|
180
|
+
addViewInfo( json, (TableRow)view );
|
181
|
+
} else if( view instanceof ViewGroup ) {
|
182
|
+
addViewInfo( json, (ViewGroup)view );
|
183
|
+
}
|
184
|
+
|
185
|
+
json.append('}');
|
186
|
+
}
|
187
|
+
|
188
|
+
json.append(']');
|
189
|
+
}
|
190
|
+
|
191
|
+
@Override
|
192
|
+
public String key() {
|
193
|
+
return "get_list_item_properties";
|
194
|
+
}
|
195
|
+
}
|
@@ -0,0 +1,136 @@
|
|
1
|
+
package sh.calaba.instrumentationbackend.actions.list;
|
2
|
+
|
3
|
+
import java.util.ArrayList;
|
4
|
+
|
5
|
+
import sh.calaba.instrumentationbackend.InstrumentationBackend;
|
6
|
+
import sh.calaba.instrumentationbackend.Result;
|
7
|
+
import sh.calaba.instrumentationbackend.actions.Action;
|
8
|
+
import android.util.Log;
|
9
|
+
import android.view.View;
|
10
|
+
import android.view.ViewGroup;
|
11
|
+
import android.widget.ListView;
|
12
|
+
import android.widget.TableRow;
|
13
|
+
import android.widget.TextView;
|
14
|
+
|
15
|
+
/**
|
16
|
+
* args:
|
17
|
+
* <ul>
|
18
|
+
* <li>1-based list index (first list is used if not specified)</li>
|
19
|
+
* <li>1-based row index (returns all rows if <=0 or not specified)</li>
|
20
|
+
* </ul>
|
21
|
+
*
|
22
|
+
* eg: (all items of 1st list) <code>performAction( 'get_list_item_text' )</code>
|
23
|
+
* eg: (all items of 2nd list) <code>performAction( 'get_list_item_text', '2' )</code>
|
24
|
+
* eg: (1st item of 2nd list) <code>performAction( 'get_list_item_text', '2' , '1' )</code>
|
25
|
+
*
|
26
|
+
* @return <code>bonusInformation</code> contain an array of Strings, one for each row in the list (or only for the specified row):
|
27
|
+
* eg: {"title":"My Title", "subtitle":"Another text field for the same list item"}
|
28
|
+
*
|
29
|
+
*
|
30
|
+
* In ruby, we can then parse the response:
|
31
|
+
* <pre>
|
32
|
+
* response_table = result['bonusInformation']
|
33
|
+
* response_table.each_with_index do | row_data, index |
|
34
|
+
* row_data = JSON.parse( row_data )
|
35
|
+
* response_table[index] = row_data
|
36
|
+
* end
|
37
|
+
* </pre>
|
38
|
+
*
|
39
|
+
* @author Nicholas Albion
|
40
|
+
*/
|
41
|
+
public class GetListItemText implements Action {
|
42
|
+
|
43
|
+
@Override
|
44
|
+
public Result execute(String... args) {
|
45
|
+
int listIndex;
|
46
|
+
int rowIndex = -1;
|
47
|
+
|
48
|
+
if( args.length == 0 ) {
|
49
|
+
listIndex = 0;
|
50
|
+
} else {
|
51
|
+
if( args.length > 1 ) {
|
52
|
+
rowIndex = (Integer.parseInt(args[1]) - 1);
|
53
|
+
}
|
54
|
+
listIndex = (Integer.parseInt(args[0]) - 1);
|
55
|
+
}
|
56
|
+
|
57
|
+
|
58
|
+
ArrayList<ListView> listViews = InstrumentationBackend.solo.getCurrentListViews();
|
59
|
+
Log.d("GetListItemText", "Found " + listViews.size() + " list views");
|
60
|
+
if( listViews == null || listViews.size() <= listIndex ) {
|
61
|
+
return new Result(false, "Could not find list #" + (listIndex + 1));
|
62
|
+
}
|
63
|
+
|
64
|
+
ListView list = listViews.get(listIndex);
|
65
|
+
Result result = new Result(true);
|
66
|
+
|
67
|
+
if( rowIndex < 0 ) {
|
68
|
+
int count = list.getChildCount();
|
69
|
+
Log.d("GetListItemText", "Found " + count + " list items");
|
70
|
+
for( int i = 0; i < count; i++ ) {
|
71
|
+
result.addBonusInformation( getListItemString( list.getChildAt(i) ) );
|
72
|
+
}
|
73
|
+
} else {
|
74
|
+
result.addBonusInformation( getListItemString( list.getChildAt(rowIndex) ) );
|
75
|
+
}
|
76
|
+
|
77
|
+
return result;
|
78
|
+
}
|
79
|
+
|
80
|
+
/**
|
81
|
+
* @return <code>bonusInformation</code> contain an array of Strings, one for each row in the list (or only for the specified row):
|
82
|
+
* eg: {"title":"My Title", "subtitle":"Another text field for the same list item"}
|
83
|
+
*/
|
84
|
+
private String getListItemString( View row ) {
|
85
|
+
StringBuilder json = new StringBuilder("{");
|
86
|
+
|
87
|
+
if( row instanceof TextView ) {
|
88
|
+
addViewInfo( json, (TextView)row );
|
89
|
+
} else if( row instanceof ViewGroup ) {
|
90
|
+
addViewInfo( json, (ViewGroup)row );
|
91
|
+
}
|
92
|
+
|
93
|
+
json.deleteCharAt( json.length() - 1 ); // remove the last comma
|
94
|
+
json.append('}');
|
95
|
+
return json.toString();
|
96
|
+
}
|
97
|
+
|
98
|
+
private void addViewInfo( StringBuilder json, TextView view ) {
|
99
|
+
int resId = view.getId();
|
100
|
+
String resIdName = view.getResources().getResourceEntryName(resId);
|
101
|
+
|
102
|
+
//json.append("\"id\":\"").append(resIdName).append("\", \"text:\"").append( ((TextView)row).getText() ).append("\"");
|
103
|
+
json.append('"').append(resIdName).append("\":\"").append( ((TextView)view).getText() ).append("\",");
|
104
|
+
}
|
105
|
+
|
106
|
+
private void addViewInfo( StringBuilder json, TableRow tableRow ) {
|
107
|
+
int count = tableRow.getVirtualChildCount();
|
108
|
+
for( int i = 0; i < count; i++ ) {
|
109
|
+
View view = tableRow.getVirtualChildAt(i);
|
110
|
+
if( view instanceof TextView ) {
|
111
|
+
addViewInfo( json, (TextView)view );
|
112
|
+
} else if( view instanceof ViewGroup ) {
|
113
|
+
addViewInfo( json, (ViewGroup)view );
|
114
|
+
}
|
115
|
+
}
|
116
|
+
}
|
117
|
+
|
118
|
+
private void addViewInfo( StringBuilder json, ViewGroup viewGroup ) {
|
119
|
+
int count = viewGroup.getChildCount();
|
120
|
+
for( int i = 0; i < count; i++ ) {
|
121
|
+
View view = viewGroup.getChildAt(i);
|
122
|
+
if( view instanceof TextView ) {
|
123
|
+
addViewInfo( json, (TextView)view );
|
124
|
+
} else if( view instanceof TableRow ) {
|
125
|
+
addViewInfo( json, (TableRow)view );
|
126
|
+
} else if( view instanceof ViewGroup ) {
|
127
|
+
addViewInfo( json, (ViewGroup)view );
|
128
|
+
}
|
129
|
+
}
|
130
|
+
}
|
131
|
+
|
132
|
+
@Override
|
133
|
+
public String key() {
|
134
|
+
return "get_list_item_text";
|
135
|
+
}
|
136
|
+
}
|