calabash-android 0.4.0.pre6 → 0.4.0.pre7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. data/bin/calabash-android +7 -0
  2. data/bin/calabash-android-build.rb +1 -1
  3. data/bin/calabash-android-console.rb +1 -1
  4. data/bin/calabash-android-run.rb +1 -1
  5. data/calabash-android.gemspec +1 -0
  6. data/irbrc +2 -0
  7. data/lib/calabash-android/helpers.rb +4 -2
  8. data/lib/calabash-android/lib/TestServer.apk +0 -0
  9. data/lib/calabash-android/operations.rb +31 -22
  10. data/lib/calabash-android/version.rb +1 -1
  11. data/test-server/instrumentation-backend/.classpath +0 -1
  12. data/test-server/instrumentation-backend/antlr/UIQuery.g +11 -2
  13. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/Command.java +4 -3
  14. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/FranklyResult.java +95 -0
  15. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/Result.java +7 -1
  16. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/HttpServer.java +15 -23
  17. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/location/FakeGPSLocation.java +13 -10
  18. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/CalabashChromeClient.java +136 -36
  19. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/DumpBodyHtml.java +38 -18
  20. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/DumpHtml.java +38 -16
  21. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/EnterTextByCssSelector.java +94 -66
  22. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/ExecuteAsyncJavascript.java +55 -33
  23. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/ExecuteJavascript.java +54 -31
  24. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/JavaScriptOperation.java +44 -0
  25. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/PressByCssSelector.java +52 -27
  26. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/QueryHelper.java +39 -32
  27. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/ScrollTo.java +56 -41
  28. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/SetPropertyByCssSelector.java +50 -25
  29. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/SetText.java +19 -22
  30. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/CompletedFuture.java +40 -0
  31. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/InvocationOperation.java +201 -0
  32. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/Operation.java +7 -0
  33. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/PropertyOperation.java +56 -0
  34. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/Query.java +144 -72
  35. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/UIQuery.tokens +15 -12
  36. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/UIQueryResultVoid.java +22 -0
  37. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ViewMapper.java +38 -11
  38. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/antlr/UIQueryLexer.java +226 -109
  39. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/antlr/UIQueryParser.java +237 -84
  40. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/PartialFutureList.java +100 -0
  41. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryAST.java +1 -1
  42. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryASTClassName.java +26 -22
  43. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryASTWith.java +170 -102
  44. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryEvaluator.java +54 -155
  45. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryUtils.java +97 -2
  46. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryVisibility.java +32 -0
  47. metadata +27 -5
  48. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/Query.java +0 -24
  49. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/Touch.java +0 -44
  50. data/test-server/instrumentation-backend/tests/sh/calaba/instrumentationbackend/query/tests/UIQueryTest.java +0 -134
@@ -1,8 +1,15 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require 'fileutils'
4
+ require 'rbconfig'
4
5
  require 'calabash-android/helpers'
5
6
 
7
+ # for ruby 1.9.1 and earlier
8
+ unless defined? RbConfig.ruby
9
+ def RbConfig.ruby
10
+ File.join(RbConfig::CONFIG["bindir"], RbConfig::CONFIG["ruby_install_name"] + RbConfig::CONFIG["EXEEXT"])
11
+ end
12
+ end
6
13
 
7
14
  require File.join(File.dirname(__FILE__), "calabash-android-helpers")
8
15
  require File.join(File.dirname(__FILE__), "calabash-android-generate")
@@ -18,7 +18,7 @@ def calabash_build(app)
18
18
  FileUtils.cp(unsigned_test_apk, "TestServer.apk")
19
19
  FileUtils.cp(File.join(File.dirname(__FILE__), '..', 'test-server/AndroidManifest.xml'), "AndroidManifest.xml")
20
20
 
21
- unless system %Q{ruby -pi.bak -e "gsub(/#targetPackage#/, '#{package_name(app)}')" AndroidManifest.xml}
21
+ unless system %Q{"#{RbConfig.ruby}" -pi.bak -e "gsub(/#targetPackage#/, '#{package_name(app)}')" AndroidManifest.xml}
22
22
  raise "Could not replace package name in manifest"
23
23
  end
24
24
 
@@ -23,5 +23,5 @@ def calabash_console(app_path = nil)
23
23
  ENV["TEST_APP_PATH"] = test_server_path
24
24
  end
25
25
 
26
- system "irb"
26
+ system "#{RbConfig.ruby} -S irb"
27
27
  end
@@ -40,7 +40,7 @@ def calabash_run(app_path = nil)
40
40
 
41
41
  STDOUT.sync = true
42
42
  arguments = ARGV - ["--no-build"]
43
- cmd = "cucumber #{arguments.join(" ")} #{env}"
43
+ cmd = "#{RbConfig.ruby} -S cucumber #{arguments.join(" ")} #{env}"
44
44
  log cmd
45
45
  exit_code = system(cmd)
46
46
 
@@ -20,5 +20,6 @@ Gem::Specification.new do |s|
20
20
  s.add_dependency( "retriable" )
21
21
  s.add_dependency( "slowhandcuke" )
22
22
  s.add_dependency( "rubyzip" )
23
+ s.add_dependency( "awesome_print" )
23
24
 
24
25
  end
data/irbrc CHANGED
@@ -1,6 +1,8 @@
1
1
  require 'rubygems'
2
2
  require 'irb/completion'
3
3
  require 'irb/ext/save-history'
4
+ require 'awesome_print'
5
+ AwesomePrint.irb!
4
6
 
5
7
  ARGV.concat [ "--readline",
6
8
  "--prompt-mode",
@@ -116,8 +116,10 @@ def fingerprint_from_apk(app_path)
116
116
  end
117
117
 
118
118
  def extract_md5_fingerprint(fingerprints)
119
- if fingerprints.encoding.name == "CP850"
120
- fingerprints = fingerprints.gsub("\xA0".force_encoding("CP850"),"")
119
+ if is_windows?
120
+ if fingerprints.encoding.name == "CP850"
121
+ fingerprints = fingerprints.gsub("\xA0".force_encoding("CP850"),"")
122
+ end
121
123
  end
122
124
 
123
125
  m = fingerprints.scan(/MD5\s*:\s*((?:\h\h:){15}\h\h)/).flatten
@@ -13,7 +13,6 @@ module Calabash module Android
13
13
 
14
14
  module Operations
15
15
 
16
-
17
16
  def log(message)
18
17
  $stdout.puts "#{Time.now.strftime("%Y-%m-%d %H:%M:%S")} - #{message}" if (ARGV.include? "-v" or ARGV.include? "--verbose")
19
18
  end
@@ -29,6 +28,7 @@ module Operations
29
28
  Then(txt)
30
29
  end
31
30
  end
31
+
32
32
  def default_device
33
33
  unless @default_device
34
34
  @default_device = Device.new(self, ENV["ADB_DEVICE_ARG"], ENV["TEST_SERVER_PORT"], ENV["APP_PATH"], ENV["TEST_APP_PATH"])
@@ -36,6 +36,10 @@ module Operations
36
36
  @default_device
37
37
  end
38
38
 
39
+ def set_default_device(device)
40
+ @default_device = device
41
+ end
42
+
39
43
  def performAction(action, *arguments)
40
44
  default_device.perform_action(action, *arguments)
41
45
  end
@@ -97,20 +101,15 @@ module Operations
97
101
  end
98
102
 
99
103
  def query(uiquery, *args)
100
- if uiquery.start_with? "webView"
101
- uiquery.slice!(0, "webView".length)
102
- if uiquery =~ /(css|xpath):\s*(.*)/
103
- r = performAction("query", $1, $2)
104
- JSON.parse(r["message"])
104
+ converted_args = []
105
+ args.each do |arg|
106
+ if arg.is_a?(Hash) and arg.count == 1
107
+ converted_args << {:method_name => arg.keys.first, :arguments => [ arg.values.first ]}
105
108
  else
106
- raise "Invalid query #{uiquery}"
109
+ converted_args << arg
107
110
  end
108
- else
109
- arguments = [*args]
110
- operation = {"method_name"=>"query", "arguments" => arguments}
111
- data = {"query" => uiquery, "operation" => operation}
112
- JSON.parse(http("/map",data))
113
111
  end
112
+ map(uiquery,:query,*converted_args)
114
113
  end
115
114
 
116
115
  def ni
@@ -134,10 +133,6 @@ module Operations
134
133
 
135
134
  class Device
136
135
 
137
- def make_default_device
138
- @cucumber_world.default_device = self
139
- end
140
-
141
136
  def initialize(cucumber_world, serial, server_port, app_path, test_server_path)
142
137
  @cucumber_world = cucumber_world
143
138
  @serial = serial
@@ -320,8 +315,8 @@ module Operations
320
315
  wake_up
321
316
  end
322
317
 
323
- env_options = {:target_package => options[:target_package] || ENV["PACKAGE_NAME"],
324
- :main_activity => options[:main_activity] || ENV["MAIN_ACTIVITY"],
318
+ env_options = {:target_package => options[:target_package] || package_name(@app_path),
319
+ :main_activity => options[:main_activity] || main_activity(@app_path),
325
320
  :debug => options[:debug] || false,
326
321
  :class => options[:class] || "sh.calaba.instrumentationbackend.InstrumentationBackend"}
327
322
 
@@ -402,17 +397,20 @@ module Operations
402
397
  end
403
398
 
404
399
  def touch(uiquery,*args)
400
+ raise "Cannot touch nil" unless uiquery
401
+
405
402
  if uiquery.instance_of? String
406
403
  elements = query(uiquery, *args)
407
404
  raise "No elements found" if elements.empty?
408
405
  element = elements.first
409
406
  else
410
407
  element = uiquery
408
+ element = element.first if element.instance_of?(Array)
411
409
  end
412
410
 
413
411
 
414
- center_x = element["frame"]["x"] + element["frame"]["width"] / 2
415
- center_y = element["frame"]["y"] + element["frame"]["height"] / 2
412
+ center_x = element["rect"]["center_x"]
413
+ center_y = element["rect"]["center_y"]
416
414
  performAction("touch_coordinate", center_x, center_y)
417
415
  end
418
416
 
@@ -527,8 +525,19 @@ module Operations
527
525
  ni
528
526
  end
529
527
 
530
- def map( query, method_name, *method_args )
531
- ni
528
+ def map(query, method_name, *method_args)
529
+ operation_map = {
530
+ :method_name => method_name,
531
+ :arguments => method_args
532
+ }
533
+ res = http("/map",
534
+ {:query => query, :operation => operation_map})
535
+ res = JSON.parse(res)
536
+ if res['outcome'] != 'SUCCESS'
537
+ screenshot_and_raise "map #{query}, #{method_name} failed because: #{res['reason']}\n#{res['details']}"
538
+ end
539
+
540
+ res['results']
532
541
  end
533
542
 
534
543
  def url_for( verb )
@@ -1,5 +1,5 @@
1
1
  module Calabash
2
2
  module Android
3
- VERSION = "0.4.0.pre6"
3
+ VERSION = "0.4.0.pre7"
4
4
  end
5
5
  end
@@ -3,7 +3,6 @@
3
3
  <classpathentry kind="src" path="src"/>
4
4
  <classpathentry kind="src" path="gen"/>
5
5
  <classpathentry kind="src" path="assets"/>
6
- <classpathentry kind="src" path="tests"/>
7
6
  <classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
8
7
  <classpathentry kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
9
8
  <classpathentry kind="lib" path="libs/robotium-solo-3.6.jar"/>
@@ -35,13 +35,22 @@ query : expr (WHITE! expr)*
35
35
  ;
36
36
 
37
37
 
38
- expr : (className | filter)
38
+ expr : (className | filter | visibility)
39
39
  ;
40
40
 
41
- className : (NAME^ | QUALIFIED_NAME^);
41
+ className : (WILDCARD^ | NAME^ | QUALIFIED_NAME^);
42
+
43
+ WILDCARD : '*';
42
44
 
43
45
  QUALIFIED_NAME : NAME ('.' NAME)+;
44
46
 
47
+ visibility : (ALL^ | VISIBLE^);
48
+
49
+ ALL : 'all';
50
+
51
+ VISIBLE : 'visible';
52
+
53
+
45
54
  filter : NAME FILTER_COLON^ (INT | STRING | BOOL | NIL);
46
55
 
47
56
  FILTER_COLON : ':'
@@ -44,8 +44,9 @@ public class Command {
44
44
 
45
45
  public Result execute() {
46
46
  final Action action = InstrumentationBackend.actions.lookup(getCommand());
47
-
48
- if ( Looper.getMainLooper().getThread() != Thread.currentThread()) {
47
+ return action.execute(getArguments());
48
+ /*
49
+ if ( Looper.getMainLooper().getThread() == Thread.currentThread()) {
49
50
  return action.execute(getArguments());
50
51
  }
51
52
 
@@ -57,7 +58,7 @@ public class Command {
57
58
  }
58
59
  });
59
60
  return result.get();
60
-
61
+ */
61
62
  }
62
63
 
63
64
  }
@@ -0,0 +1,95 @@
1
+ package sh.calaba.instrumentationbackend;
2
+
3
+ import java.io.CharArrayWriter;
4
+ import java.io.IOException;
5
+ import java.io.PrintWriter;
6
+ import java.util.Collections;
7
+ import java.util.HashMap;
8
+ import java.util.List;
9
+ import java.util.Map;
10
+
11
+ import sh.calaba.org.codehaus.jackson.map.ObjectMapper;
12
+
13
+ /**
14
+ * Represents a response in the Frankly protocol.
15
+ * This protocol is a JSON over HTTP protocol which is
16
+ * used across Calabash iOS, Calabash Android and Frank.
17
+ * @author krukow
18
+ * @see https://github.com/moredip/Frank/blob/master/doc/frankly.md
19
+ *
20
+ */
21
+ public class FranklyResult {
22
+
23
+ final boolean success;
24
+ final String reason;
25
+ final String detail;
26
+ @SuppressWarnings("rawtypes")
27
+ final List results;
28
+
29
+
30
+ @SuppressWarnings({ "rawtypes" })
31
+ public FranklyResult(boolean success, List results, String reason,
32
+ String detail) {
33
+ super();
34
+ this.success = success;
35
+ this.results = results;
36
+ this.reason = reason;
37
+ this.detail = detail;
38
+ }
39
+
40
+ public static FranklyResult fromThrowable(Throwable t) {
41
+ CharArrayWriter caw = new CharArrayWriter();
42
+ t.printStackTrace(new PrintWriter(caw));
43
+ return new FranklyResult(false,Collections.EMPTY_LIST,t.getMessage(),caw.toString());
44
+ }
45
+
46
+ public static FranklyResult emptyResult() {
47
+ return new FranklyResult(true,Collections.EMPTY_LIST,null,null);
48
+ }
49
+
50
+ public static FranklyResult failedResult(String message,String detail) {
51
+ return new FranklyResult(false,Collections.EMPTY_LIST,message,detail);
52
+ }
53
+
54
+ public String asJson() {
55
+ ObjectMapper mapper = new ObjectMapper();
56
+
57
+ try {
58
+ return mapper.writeValueAsString(asMap());
59
+ } catch (IOException e) {
60
+ throw new RuntimeException("Could not convert result to json", e);
61
+ }
62
+ }
63
+
64
+ public Map<String,Object> asMap()
65
+ {
66
+ Map<String,Object> result = new HashMap<String, Object>();
67
+ result.put("outcome", this.success ? "SUCCESS" : "ERROR");
68
+
69
+ if (this.success)
70
+ {
71
+ result.put("results",this.results);
72
+ }
73
+ else
74
+ {
75
+ result.put("reason", this.reason);
76
+ if (this.detail != null)
77
+ {
78
+ result.put("detail", this.detail);
79
+ }
80
+ }
81
+ return result;
82
+ }
83
+
84
+ @Override
85
+ public String toString()
86
+ {
87
+ return "FranklyResult [success=" + success + ", reason=" + reason
88
+ + ", details=" + detail + ", results=" + results + "]";
89
+ }
90
+
91
+ @SuppressWarnings("rawtypes")
92
+ public static FranklyResult successResult(List result) {
93
+ return new FranklyResult(true, result, null,null);
94
+ }
95
+ }
@@ -22,7 +22,13 @@ public class Result {
22
22
  this.success = success;
23
23
  this.message = message;
24
24
  }
25
-
25
+
26
+ public Result(boolean success, List<String> messages) {
27
+ this.success = success;
28
+ this.message = null;
29
+ this.bonusInformation = messages;
30
+ }
31
+
26
32
  public String getMessage() {
27
33
  return message;
28
34
  }
@@ -14,13 +14,13 @@ import java.util.concurrent.locks.Lock;
14
14
  import java.util.concurrent.locks.ReentrantLock;
15
15
 
16
16
  import sh.calaba.instrumentationbackend.Command;
17
+ import sh.calaba.instrumentationbackend.FranklyResult;
17
18
  import sh.calaba.instrumentationbackend.InstrumentationBackend;
18
19
  import sh.calaba.instrumentationbackend.Result;
19
20
  import sh.calaba.instrumentationbackend.query.Query;
20
21
  import sh.calaba.instrumentationbackend.query.QueryResult;
21
22
  import sh.calaba.org.codehaus.jackson.map.DeserializationConfig.Feature;
22
23
  import sh.calaba.org.codehaus.jackson.map.ObjectMapper;
23
- import sh.calaba.org.codehaus.jackson.type.TypeReference;
24
24
  import android.graphics.Bitmap;
25
25
  import android.util.Log;
26
26
  import android.view.View;
@@ -75,6 +75,7 @@ public class HttpServer extends NanoHTTPD {
75
75
  return new NanoHTTPD.Response(HTTP_OK, MIME_HTML, "pong");
76
76
 
77
77
  } else if (uri.endsWith("/map")) {
78
+ FranklyResult errorResult = null;
78
79
  try {
79
80
  String commandString = params.getProperty("json");
80
81
  ObjectMapper mapper = new ObjectMapper();
@@ -85,32 +86,23 @@ public class HttpServer extends NanoHTTPD {
85
86
  String methodName = (String) op.get("method_name");
86
87
  List arguments = (List) op.get("arguments");
87
88
 
88
- QueryResult queryResult = new Query(uiQuery,arguments).execute();
89
+ //For now we only support query and query_all
90
+ //query_all includes also invisible views, while query filters them
91
+ boolean includeInVisible = "query_all".equals(methodName);
92
+
93
+
94
+ List queryResult = new Query(uiQuery,arguments).executeQuery();
89
95
 
90
- return new NanoHTTPD.Response(HTTP_OK, "application/json;charset=utf-8",
91
- queryResult.asJson());
92
- } catch (IOException e) {
93
- e.printStackTrace();
96
+ return new NanoHTTPD.Response(HTTP_OK, "application/json;charset=utf-8",
97
+ FranklyResult.successResult(queryResult).asJson());
94
98
  } catch (Exception e ) {
95
- System.err.println("Query failed!");
96
- e.printStackTrace();
99
+ e.printStackTrace();
100
+ errorResult = FranklyResult.fromThrowable(e);
97
101
  }
98
- return new NanoHTTPD.Response(HTTP_INTERNALERROR, MIME_HTML, "Query failed");
102
+ return new NanoHTTPD.Response(HTTP_OK, "application/json;charset=utf-8", errorResult.asJson());
99
103
  } else if (uri.endsWith("/query")) {
100
- try {
101
- String commandString = params.getProperty("json");
102
- ObjectMapper mapper = new ObjectMapper();
103
- Map<String, String> command = mapper.readValue(commandString,
104
- new TypeReference<Map<String, String>>() {
105
- });
106
- QueryResult result = new Query(command.get("query")).executeInMainThread();
107
- return new NanoHTTPD.Response(HTTP_OK, MIME_HTML,
108
- result.asJson());
109
- } catch (IOException e) {
110
- e.printStackTrace();
111
- return new Response(HTTP_INTERNALERROR, MIME_PLAINTEXT,
112
- "Could not parse arguments as JSON");
113
- }
104
+ return new Response(HTTP_BADREQUEST, MIME_PLAINTEXT,
105
+ "/query endpoint is discontinued - use /map with operation query");
114
106
  } else if (uri.endsWith("/kill")) {
115
107
  lock.lock();
116
108
  try {
@@ -10,6 +10,8 @@ import android.location.Location;
10
10
  import android.location.LocationManager;
11
11
  import android.location.LocationProvider;
12
12
 
13
+ import java.lang.reflect.Method;
14
+
13
15
 
14
16
  public class FakeGPSLocation implements Action {
15
17
 
@@ -73,15 +75,22 @@ public class FakeGPSLocation implements Action {
73
75
 
74
76
  private void setLocation(LocationManager locationManager, String locationProvider, double latitude, double longitude) {
75
77
 
76
- //locationManager.clearTestProviderLocation(locationProvider);
77
-
78
78
  Location location = new Location(locationProvider);
79
79
  location.setLatitude(latitude);
80
80
  location.setLongitude(longitude);
81
81
  location.setAccuracy(1);
82
82
  location.setTime(System.currentTimeMillis());
83
83
 
84
- locationManager.setTestProviderLocation(locationProvider, location);
84
+ try {
85
+ Method makeComplete = Location.class.getMethod("makeComplete");
86
+ if (makeComplete != null) {
87
+ makeComplete.invoke(location);
88
+ }
89
+ } catch (Exception e) {
90
+ //Method only available in Jelly Bean
91
+ }
92
+
93
+ locationManager.setTestProviderLocation(locationProvider, location);
85
94
  }
86
95
 
87
96
  public void finish() {
@@ -93,13 +102,7 @@ public class FakeGPSLocation implements Action {
93
102
  public String key() {
94
103
  return "set_gps_coordinates";
95
104
  }
96
-
97
- /**
98
- * Causes error if Device does not support given provider
99
- *
100
- * @param provider
101
- * @return
102
- */
105
+
103
106
  private boolean doesDeviceProvideGPS() {
104
107
  LocationManager locationManager = (LocationManager) InstrumentationBackend.solo.getCurrentActivity().getSystemService(Context.LOCATION_SERVICE);
105
108
  if (locationManager.getProvider(LocationManager.GPS_PROVIDER) == null) {