testautoa 0.4.3 → 0.4.4

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -14,6 +14,8 @@ def build
14
14
  ant_executable,
15
15
  "clean",
16
16
  "package",
17
+ "-debug",
18
+ "-Dtools.dir=\"#{tools_dir}\"",
17
19
  "-Dandroid.api.level=17",
18
20
  "-Dversion=#{Calabash::Android::VERSION}",
19
21
  ]
@@ -11,7 +11,8 @@ def calabash_build(app)
11
11
  FileUtils.mkdir_p File.dirname(test_server_file_name) unless File.exist? File.dirname(test_server_file_name)
12
12
 
13
13
  unsigned_test_apk = File.join(File.dirname(__FILE__), '..', 'lib/calabash-android/lib/TestServer.apk')
14
- android_platform = Dir["#{ENV["ANDROID_HOME"].gsub("\\", "/")}/platforms/android-*"].last
14
+ platforms = Dir["#{android_home_path}/platforms/android-*"].sort_by { |item| '%08s' % item.split('-').last }
15
+ android_platform = platforms.last
15
16
  raise "No Android SDK found in #{ENV["ANDROID_HOME"].gsub("\\", "/")}/platforms/" unless android_platform
16
17
  Dir.mktmpdir do |workspace_dir|
17
18
  Dir.chdir(workspace_dir) do
@@ -26,7 +27,7 @@ def calabash_build(app)
26
27
  raise "Could not replace test package name in manifest"
27
28
  end
28
29
 
29
- unless system %Q{"#{ENV["ANDROID_HOME"]}/platform-tools/aapt" package -M AndroidManifest.xml -I "#{android_platform}/android.jar" -F dummy.apk}
30
+ unless system %Q{"#{tools_dir}/aapt" package -M AndroidManifest.xml -I "#{android_platform}/android.jar" -F dummy.apk}
30
31
  raise "Could not create dummy.apk"
31
32
  end
32
33
 
@@ -44,4 +45,4 @@ def calabash_build(app)
44
45
  end
45
46
  end
46
47
  puts "Done signing the test server. Moved it to #{test_server_file_name}"
47
- end
48
+ end
@@ -1,5 +1,5 @@
1
- WAIT_TIMEOUT = ENV['WAIT_TIMEOUT'] || 30
2
- STEP_PAUSE = (ENV['STEP_PAUSE'] || 0.5).to_f
1
+ WAIT_TIMEOUT = ENV['WAIT_TIMEOUT'] || 60
2
+ STEP_PAUSE = (ENV['STEP_PAUSE'] || 1.0).to_f
3
3
 
4
4
  require 'calabash-android/steps/additions_manual_steps'
5
5
  require 'calabash-android/steps/app_steps'
@@ -244,6 +244,10 @@ Simulates that the user pressed the toggle button with the label text of the l10
244
244
  Then /^I wait for the translated "([^\"]*)" l10nkey to appear$/
245
245
  Waits until the text of the translated l10nkey is displayed.
246
246
 
247
+ Note: you can assert or press interface elements using [Android's String resources](http://developer.android.com/reference/android/R.string.html) by passing a package in a custom step:
248
+
249
+ performAction('press_l10n_element', 'ok', nil, 'android')
250
+
247
251
  Rotation
248
252
  --------
249
253
 
@@ -80,6 +80,16 @@ def sign_apk(app_path, dest_path)
80
80
  end
81
81
  end
82
82
 
83
+ def tools_dir
84
+ dirs = Dir["#{android_home_path}/build-tools/*/"] + Dir["#{android_home_path}/platform-tools/"]
85
+ raise "Could not find tools directory in ANDROID_HOME" if dirs.empty?
86
+ dirs.first
87
+ end
88
+
89
+ def android_home_path
90
+ ENV["ANDROID_HOME"].gsub("\\", "/")
91
+ end
92
+
83
93
  def read_keystore_info
84
94
  keystore = default_keystore
85
95
 
@@ -237,7 +237,11 @@ module Operations
237
237
  end
238
238
 
239
239
  def app_running?
240
- `#{adb_command} shell ps`.include?(ENV["PROCESS_NAME"] || package_name(@app_path))
240
+ begin
241
+ http("/ping") == "pong"
242
+ rescue
243
+ false
244
+ end
241
245
  end
242
246
 
243
247
  def keyguard_enabled?
@@ -277,12 +281,9 @@ module Operations
277
281
  http.read_timeout = options[:read_timeout] if options[:read_timeout]
278
282
  resp = http.post(path, "#{data.to_json}", {"Content-Type" => "application/json;charset=utf-8"})
279
283
  resp.body
280
- rescue Exception => e
281
- if app_running?
284
+ rescue EOFError => e
285
+ log "It looks like your app is no longer running. \nIt could be because of a crash or because your test script shut it down."
282
286
  raise e
283
- else
284
- raise "App no longer running"
285
- end
286
287
  end
287
288
  end
288
289
 
@@ -1,5 +1,5 @@
1
1
  module Calabash
2
2
  module Android
3
- VERSION = "0.4.3"
3
+ VERSION = "0.4.4"
4
4
  end
5
5
  end
@@ -22,7 +22,7 @@
22
22
 
23
23
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
24
24
  <uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />
25
- <uses-permission android:name="android.permission.ACCESS_COURSE_LOCATION"/>
25
+ <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
26
26
  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
27
27
  <uses-permission android:name="android.permission.INTERNET" />
28
28
 
@@ -6,7 +6,6 @@
6
6
 
7
7
  <property name="adb.device.arg" value="" />
8
8
  <property environment="env"/>
9
- <property file="build.properties"/>
10
9
  <property name="staging.dir" location="staging"/>
11
10
  <property name="bin.dir" location="bin"/>
12
11
  <property name="test.app.aapt" location="${bin.dir}/Test_aapt.apk"/>
@@ -14,24 +13,19 @@
14
13
  <property name="test.app.unsigned" location="${bin.dir}/Test_unsigned.apk"/>
15
14
  <property name="calabashjs.dir" location="calabash-js/src"/>
16
15
 
17
-
18
16
  <!-- Windows support -->
19
17
  <condition property="bat" value=".bat" else=""><os family="windows" /></condition>
20
- <property name="dx" location="${env.ANDROID_HOME}/platform-tools/dx${bat}" />
21
- <property name="apkbuilder" location="${env.ANDROID_HOME}/tools/apkbuilder${bat}" />
22
18
 
19
+ <property name="dx" location="${tools.dir}/dx${bat}" />
20
+ <property name="aapt" location="${tools.dir}/aapt${bat}" />
21
+
23
22
  <property name="android.lib" location="${env.ANDROID_HOME}/platforms/android-${android.api.level}/android.jar"/>
24
23
  <path id="android.antlibs">
24
+ <pathelement path="${env.ANDROID_HOME}/tools/lib/ant-tasks.jar" />
25
25
  <pathelement path="${env.ANDROID_HOME}/tools/lib/anttasks.jar" />
26
26
  <pathelement path="${env.ANDROID_HOME}/tools/lib/sdklib.jar" />
27
27
  <pathelement path="${env.ANDROID_HOME}/tools/lib/androidprefs.jar" />
28
28
  </path>
29
- <taskdef name="xpath" classname="com.android.ant.XPathTask" classpathref="android.antlibs"/>
30
- <taskdef name="aapt" classname="com.android.ant.AaptExecTask" classpathref="android.antlibs" />
31
- <taskdef name="apkbuilder" classname="com.android.ant.ApkBuilderTask" classpathref="android.antlibs" />
32
-
33
-
34
-
35
29
 
36
30
  <path id="jar.libs.ref">
37
31
  <fileset dir="${staging.dir}/libs/" includes="*.jar" />
@@ -103,7 +97,7 @@
103
97
  </target>
104
98
 
105
99
  <target name="-aapt">
106
- <exec executable="${env.ANDROID_HOME}/platform-tools/aapt" failonerror="yes">
100
+ <exec executable="${aapt}" failonerror="yes">
107
101
  <arg value="package" />
108
102
  <arg value="-f" />
109
103
  <arg value="-F" />
@@ -131,12 +125,11 @@
131
125
  </target>
132
126
 
133
127
  <target name="-apk">
134
- <exec executable="${apkbuilder}" failonerror="yes">
128
+ <exec executable="java" failonerror="yes">
129
+ <arg value="-jar" />
130
+ <arg value="${staging.dir}/CalabashApkBuilder.jar" />
135
131
  <arg file="${test.app.unsigned}" />
136
- <arg value="-u" />
137
- <arg value="-z" />
138
132
  <arg file="${test.app.aapt}" />
139
- <arg value="-f" />
140
133
  <arg file="${dex.file}" />
141
134
  </exec>
142
135
  </target>
@@ -36,10 +36,6 @@
36
36
  {
37
37
  res.href = object.href;
38
38
  }
39
- if (object.hasOwnProperty('value'))
40
- {
41
- res.value = object.value || '';
42
- }
43
39
  res.html = object.outerHTML || '';
44
40
  res.textContent = object.textContent;
45
41
  return res;
@@ -1,49 +1,49 @@
1
1
  (function () {
2
- function simulateKeyEvent(elem, character) {
3
- var ch = character.charCodeAt(0);
4
-
5
- var evt;
6
- evt = document.createEvent('KeyboardEvent');
7
- evt.initKeyboardEvent('keydown', true, true, window, 0, 0, 0, 0, 0, ch);
8
- elem.dispatchEvent(evt);
9
-
10
- evt = document.createEvent('KeyboardEvent');
11
- evt.initKeyboardEvent('keyup', true, true, window, 0, 0, 0, 0, 0, ch);
12
- elem.dispatchEvent(evt);
13
- evt = document.createEvent('KeyboardEvent');
14
- evt.initKeyboardEvent('keypress', true, true, window, 0, 0, 0, 0, 0, ch);
15
- elem.dispatchEvent(evt);
16
- }
17
-
18
-
19
- function enterTextIntoInputField(elem, text) {
20
- elem.value = "";
21
- for (var i = 0; i < text.length; i++) {
22
- var ch = text.charAt(i);
23
- elem.value += ch;
24
- simulateKeyEvent(elem, ch);
25
- }
26
- }
27
-
28
-
29
- function fireHTMLEvent(elem, eventName) {
30
- var evt = document.createEvent("HTMLEvents");
31
- evt.initEvent(eventName, true, true );
32
- return !elem.dispatchEvent(evt);
33
- }
34
-
35
- function selectInputField(elem) {
36
- elem.click();
37
- elem.focus();
38
- }
39
-
40
-
41
- function deselectInputField(elem) {
42
- fireHTMLEvent(elem, 'change');
43
- fireHTMLEvent(elem, 'blur');
44
- }
45
-
46
-
2
+ function simulateKeyEvent(elem, character) {
3
+ var ch = character.charCodeAt(0);
4
+
5
+ var evt;
6
+ evt = document.createEvent('KeyboardEvent');
7
+ evt.initKeyboardEvent('keydown', true, true, window, 0, 0, 0, 0, 0, ch);
8
+ elem.dispatchEvent(evt);
9
+
10
+ evt = document.createEvent('KeyboardEvent');
11
+ evt.initKeyboardEvent('keyup', true, true, window, 0, 0, 0, 0, 0, ch);
12
+ elem.dispatchEvent(evt);
13
+ evt = document.createEvent('KeyboardEvent');
14
+ evt.initKeyboardEvent('keypress', true, true, window, 0, 0, 0, 0, 0, ch);
15
+ elem.dispatchEvent(evt);
16
+ }
17
+
18
+
19
+ function enterTextIntoInputField(elem, text) {
20
+ elem.value = "";
21
+ for (var i = 0; i < text.length; i++) {
22
+ var ch = text.charAt(i);
23
+ elem.value += ch;
24
+ simulateKeyEvent(elem, ch);
25
+ }
26
+ }
27
+
28
+
29
+ function fireHTMLEvent(elem, eventName) {
30
+ var evt = document.createEvent("HTMLEvents");
31
+ evt.initEvent(eventName, true, true );
32
+ return !elem.dispatchEvent(evt);
33
+ }
34
+
35
+ function selectInputField(elem) {
36
+ elem.click();
37
+ elem.focus();
38
+ }
39
+
40
+
41
+ function deselectInputField(elem) {
42
+ fireHTMLEvent(elem, 'change');
43
+ fireHTMLEvent(elem, 'blur');
44
+ }
45
+
46
+
47
47
  /** David Mark's isHostMethod function,
48
48
  * http://peter.michaux.ca/articles/feature-detection-state-of-the-art-browser-scripting
49
49
  * Modified to use strict equality
@@ -72,7 +72,7 @@
72
72
  }
73
73
  else if (object instanceof Node)//TODO: support for frames!
74
74
  {
75
- res = {};
75
+ res = {}
76
76
  if (isHostMethod(object,'getBoundingClientRect'))
77
77
  {
78
78
  res['rect'] = object.getBoundingClientRect();
@@ -81,9 +81,6 @@
81
81
  res.nodeName = object.nodeName;
82
82
  res.id = object.id || '';
83
83
  res['class'] = object.className || '';
84
- if (object.hasOwnProperty('value')) {
85
- res.value = object.value;
86
- }
87
84
  res.html = object.outerHTML || '';
88
85
  res.nodeValue = object.nodeValue;
89
86
  }
@@ -105,26 +102,23 @@
105
102
  }
106
103
  return res;
107
104
  }
108
-
105
+
109
106
  ///TODO: no support for now frames
110
107
  //idea would be map XPath across window.frames
111
108
  //must take care of visibility questions
112
109
 
113
110
  try
114
- {
115
- var exp = JSON.parse('%@')/* dynamic */,
116
- el,
117
- text = '%@',
118
- i,N;
119
-
111
+ {
112
+ var exp = JSON.parse('%@')/* dynamic */,
113
+ el,
114
+ text = '%@',
115
+ i,N;
116
+
120
117
  el=document.elementFromPoint(exp.rect.left, exp.rect.top);
121
- if(exp.id){
122
- el = document.getElementById(exp.id);
123
- }
124
118
  if (/input/i.test(el.tagName))
125
119
  {
126
- selectInputField(el);
127
- enterTextIntoInputField(el, text);
120
+ selectInputField(el);
121
+ enterTextIntoInputField(el, text);
128
122
  }
129
123
  else
130
124
  {
@@ -136,4 +130,4 @@
136
130
  return JSON.stringify({error:'Exception while running query: '+exp, details:e.toString()})
137
131
  }
138
132
  return JSON.stringify(toJSON(el));
139
- })();
133
+ })();
@@ -13,15 +13,20 @@ public class L10nHelper {
13
13
  * get the translated value based on the current active locale.
14
14
  *
15
15
  * @param l10nKey The l10n key to use
16
+ * @param pckg Optional package to find the resource, defaults to the application's package if null
16
17
  * @return The translated value.
17
18
  */
18
- public static String getValue(String l10nKey) {
19
+ public static String getValue(String l10nKey, String pckg) {
20
+
21
+ if(pckg == null){
22
+ pckg = InstrumentationBackend.solo.getCurrentActivity().getPackageName();
23
+ }
24
+
19
25
  int resourceId =
20
26
  InstrumentationBackend.solo
21
27
  .getCurrentActivity()
22
28
  .getResources()
23
- .getIdentifier(l10nKey, "string",
24
- InstrumentationBackend.solo.getCurrentActivity().getPackageName());
29
+ .getIdentifier(l10nKey, "string", pckg);
25
30
 
26
31
  String localizedString =
27
32
  InstrumentationBackend.solo.getCurrentActivity().getResources().getString(resourceId);
@@ -21,7 +21,9 @@ public class PressElement implements Action {
21
21
  public Result execute(String... args) {
22
22
  String l10nKey = args[0];
23
23
  String elementType = args.length > 1 ? args[1] : null;
24
- String myLocalizedString = L10nHelper.getValue(l10nKey);
24
+ String pckg = (args.length > 2)? args[2] : null;
25
+
26
+ String myLocalizedString = L10nHelper.getValue(l10nKey, pckg);
25
27
  InstrumentationBackend.solo.searchText(myLocalizedString);
26
28
  if (elementType == null) {
27
29
  InstrumentationBackend.solo.clickOnText(myLocalizedString);
@@ -28,13 +28,14 @@ public class WaitForElement implements Action {
28
28
  @Override
29
29
  public Result execute(String... args) {
30
30
  String l10nKey = args[0];
31
+ String pckg = (args.length > 1)? args[1] : null;
31
32
 
32
- String myLocalizedString = L10nHelper.getValue(l10nKey);
33
+ String myLocalizedString = L10nHelper.getValue(l10nKey, pckg);
33
34
  boolean timedOut = !InstrumentationBackend.solo.waitForText(
34
35
  myLocalizedString, 1, 90000);
35
36
  if (timedOut) {
36
37
  return new Result(false, "Time out while waiting for text:"
37
- + args[0]);
38
+ + args[0] + ", package: " + pckg);
38
39
  } else {
39
40
  return Result.successResult();
40
41
  }
@@ -11,7 +11,10 @@ public class EnterTextById implements Action {
11
11
 
12
12
  @Override
13
13
  public Result execute(String... args) {
14
- final View view = TestHelpers.getViewById(args[1]);
14
+ if(args[1] == null) {
15
+ return Result.failedResult("Input text cannot be null");
16
+ }
17
+ View view = TestHelpers.getViewById(args[1]);
15
18
  if(view == null) {
16
19
  return new Result(false, "No view found with id: '" + args[1] + "'");
17
20
  } else if (!(view instanceof EditText)) {
@@ -17,7 +17,7 @@ public class WaitForViewById implements Action {
17
17
  if( getViewById(viewId, 60000) != null ) {
18
18
  return Result.successResult();
19
19
  } else {
20
- return new Result(false, "Timed out while waiting for view with id:'" + viewId + "'");
20
+ return new Result(false, "Waiting for view with id '" + viewId + "' to be visible timed out");
21
21
  }
22
22
  } catch( InterruptedException e ) {
23
23
  return Result.fromThrowable(e);
@@ -25,22 +25,29 @@ public class WaitForViewById implements Action {
25
25
  }
26
26
 
27
27
  protected View getViewById( String viewId, long timeout ) throws InterruptedException {
28
- System.out.println("Waiting for view with id '" + viewId + "'");
28
+
29
+ System.out.println("Waiting for view with id '" + viewId + "' to appear");
30
+
31
+ View view = TestHelpers.getViewById(viewId);
32
+
33
+ // no view, quick exit
34
+ if(view == null){
35
+ throw new IllegalArgumentException("Could not find view with id '" + viewId + "'");
36
+ }
37
+
38
+ System.out.println("Waiting for view with id '" + viewId + "' found view " + view);
39
+
29
40
  long endTime = System.currentTimeMillis() + timeout;
30
41
  while (System.currentTimeMillis() < endTime) {
31
- View view = TestHelpers.getViewById(viewId);
32
- System.out.println("Waiting for view with id '" + viewId + "' found view " + view);
33
-
34
- if (view != null) {
35
- System.out.println("Waiting for view with id '" + viewId + "' Success");
42
+ if (view.getVisibility() == View.VISIBLE) {
43
+ System.out.println("View with id '" + viewId + "' is visible, success");
36
44
  return view;
37
45
  } else {
38
- System.out.println("Waiting for view with id '" + viewId + "' sleeping...");
46
+ System.out.println("View with id '" + viewId + "' is not visible, sleeping...");
39
47
  Thread.sleep(500);
40
48
  }
41
49
  }
42
50
 
43
- System.out.println("Waiting for view with id '" + viewId + "' Timed out");
44
51
  return null;
45
52
  }
46
53
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: testautoa
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.3
4
+ version: 0.4.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-05-01 00:00:00.000000000 Z
12
+ date: 2013-05-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: cucumber
@@ -123,6 +123,22 @@ dependencies:
123
123
  - - ! '>='
124
124
  - !ruby/object:Gem::Version
125
125
  version: '0'
126
+ - !ruby/object:Gem::Dependency
127
+ name: nokogiri
128
+ requirement: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ! '>='
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ type: :runtime
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ! '>='
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
126
142
  description: Description
127
143
  email:
128
144
  executables:
@@ -197,10 +213,11 @@ files:
197
213
  - test-server/instrumentation-backend/.project
198
214
  - test-server/instrumentation-backend/.settings/org.eclipse.jdt.core.prefs
199
215
  - test-server/instrumentation-backend/AndroidManifest.xml
216
+ - test-server/instrumentation-backend/CalabashApkBuilder.jar
200
217
  - test-server/instrumentation-backend/antlr.sh
201
218
  - test-server/instrumentation-backend/antlr/UIQuery.g
202
219
  - test-server/instrumentation-backend/antlr/UIQuery.tokens
203
- - test-server/instrumentation-backend/assets/foo.bar
220
+ - test-server/instrumentation-backend/assets/.gitkeep
204
221
  - test-server/instrumentation-backend/build-libs/antlr-3.4-complete.jar
205
222
  - test-server/instrumentation-backend/build-libs/junit.jar
206
223
  - test-server/instrumentation-backend/build.xml
@@ -875,4 +892,3 @@ signing_key:
875
892
  specification_version: 3
876
893
  summary: Summary
877
894
  test_files: []
878
- has_rdoc: