selendroid 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +19 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +15 -0
- data/README.md +48 -0
- data/Rakefile +1 -0
- data/bin/selendroid +59 -0
- data/lib/selendroid.rb +3 -0
- data/lib/selendroid/selendroid_builder.rb +64 -0
- data/lib/selendroid/version.rb +3 -0
- data/selendroid-prebuild/AndroidManifest.xml +22 -0
- data/selendroid-prebuild/selendroid-server.apk +0 -0
- data/selendroid.gemspec +19 -0
- metadata +85 -0
data/.gitignore
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
selendroid-test-app-0.1-SNAPSHOT.apk
|
10
|
+
selendroid-server-0.0.1.apk
|
11
|
+
coverage
|
12
|
+
doc/
|
13
|
+
lib/bundler/man
|
14
|
+
pkg
|
15
|
+
rdoc
|
16
|
+
spec/reports
|
17
|
+
test/tmp
|
18
|
+
test/version_tmp
|
19
|
+
tmp
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
Copyright (c) 2013 Dary, Dominik
|
2
|
+
|
3
|
+
Apache License 2.0
|
4
|
+
|
5
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
you may not use this file except in compliance with the License.
|
7
|
+
You may obtain a copy of the License at
|
8
|
+
|
9
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
|
11
|
+
Unless required by applicable law or agreed to in writing, software
|
12
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
See the License for the specific language governing permissions and
|
15
|
+
limitations under the License.
|
data/README.md
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
Selendroid
|
2
|
+
==========
|
3
|
+
|
4
|
+
Selendroid is an attempt to implement the Selenium JSON Wire Protocol for Android native and hybrid apps.
|
5
|
+
|
6
|
+
Getting started
|
7
|
+
---------------
|
8
|
+
|
9
|
+
Selendroid is based on the Android instrumentation framework, so therefor only testing one specific app is supported.
|
10
|
+
Selendroid-server in combination with the application under test (aut) must be installed on the device in order to be able to run automated end-to-end tests.
|
11
|
+
|
12
|
+
To write and run tests with selendroid, first a customized selendroid-server for your aut must be created. To simplify this process I have created a Ruby gem:
|
13
|
+
|
14
|
+
sudo gem install selendroid
|
15
|
+
selendroid build pathToYour.apk
|
16
|
+
|
17
|
+
Now you will find your customized selendroid-server. To run the server:
|
18
|
+
|
19
|
+
# start the selendroid server:
|
20
|
+
adb shell am instrument -e main_activity 'org.openqa.selendroid.testapp.HomeScreenActivity' org.openqa.selendroid.server/org.openqa.selendroid.server.ServerInstrumentation
|
21
|
+
# activate port forwarding.
|
22
|
+
adb forward tcp:8080 tcp:8080
|
23
|
+
|
24
|
+
A sample test looks like:
|
25
|
+
|
26
|
+
driver = new AndroidDriver(new URL("http://localhost:8080/wd/hub"), getDefaultCapabilities());
|
27
|
+
driver.findElement(By.id("startUserRegistration")).click();
|
28
|
+
|
29
|
+
WebDriverWait wait = new WebDriverWait(driver, 5);
|
30
|
+
WebElement inputUsername =
|
31
|
+
wait.until(ExpectedConditions.presenceOfElementLocated(By.id("inputUsername")));
|
32
|
+
inputUsername.sendKeys(user.getUsername());
|
33
|
+
Assert.assertEquals(nameInput.getText(), "Mr. Burns");
|
34
|
+
nameInput.clear();
|
35
|
+
nameInput.sendKeys(user.getName());
|
36
|
+
takeScreenShot("User data entered.");
|
37
|
+
driver.findElement(By.id("btnRegisterUser")).click();
|
38
|
+
|
39
|
+
More details about selendroid can be found in the [wiki](https://github.com/DominikDary/selendroid/wiki/).
|
40
|
+
|
41
|
+
Current state
|
42
|
+
-------------
|
43
|
+
|
44
|
+
Please keep in mind that this project is in very early stages. Help is appreciated. Reach us out in the issues or via email.
|
45
|
+
|
46
|
+
You can track the current progress on the following [link](https://github.com/DominikDary/selendroid/wiki/JSON-Wire-Protocol)
|
47
|
+
|
48
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/selendroid
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'fileutils'
|
4
|
+
require 'selendroid/selendroid_builder'
|
5
|
+
require 'rbconfig'
|
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
|
13
|
+
|
14
|
+
def print_comamndline_help
|
15
|
+
puts <<EOF
|
16
|
+
Usage: selendroid <command-name> [parameters]
|
17
|
+
<command-name> can be one of
|
18
|
+
help
|
19
|
+
Prints more detailed help information.
|
20
|
+
build <apk>
|
21
|
+
Builds the selendroid-server for the given apk.
|
22
|
+
To find help, please visit the official selendroid wiki: http://goo.gl/z30pj
|
23
|
+
EOF
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
def is_apk_file?(file_path)
|
28
|
+
file_path.end_with? ".apk" and File.exist? file_path
|
29
|
+
end
|
30
|
+
|
31
|
+
def relative_to_full_path(file_path)
|
32
|
+
File.expand_path(file_path)
|
33
|
+
end
|
34
|
+
|
35
|
+
def raise_if_android_home_not_set
|
36
|
+
raise "Please set the ANDROID_HOME environment variable" unless ENV["ANDROID_HOME"]
|
37
|
+
end
|
38
|
+
|
39
|
+
if (ARGV.length == 0)
|
40
|
+
print_comamndline_help
|
41
|
+
exit 0
|
42
|
+
end
|
43
|
+
cmd = ARGV.shift
|
44
|
+
if cmd == 'help'
|
45
|
+
print_comamndline_help
|
46
|
+
exit 0
|
47
|
+
elsif cmd == 'build'
|
48
|
+
raise_if_android_home_not_set
|
49
|
+
puts "Please specify the app you want to build a selendroid-server for" if (ARGV.empty? or not is_apk_file?(ARGV.first))
|
50
|
+
while not ARGV.empty? and is_apk_file?(ARGV.first)
|
51
|
+
rebuild_selendroid(relative_to_full_path(ARGV.shift))
|
52
|
+
end
|
53
|
+
exit 0
|
54
|
+
else
|
55
|
+
print_comamndline_help
|
56
|
+
exit 0
|
57
|
+
end
|
58
|
+
|
59
|
+
|
data/lib/selendroid.rb
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
require "selendroid/version"
|
2
|
+
require 'zip/zip'
|
3
|
+
require 'tempfile'
|
4
|
+
|
5
|
+
def rebuild_selendroid(app)
|
6
|
+
aut_base_package = %x[ aapt dump badging '#{app}' | grep package | cut -d '=' -f2-|awk '{ print $1}' | tr -d "'" ]
|
7
|
+
puts "Building selendroid-server for package #{aut_base_package}"
|
8
|
+
|
9
|
+
test_server_file_name = selendroid_server_path(aut_base_package)
|
10
|
+
FileUtils.mkdir_p File.dirname(test_server_file_name) unless File.exist? File.dirname(test_server_file_name)
|
11
|
+
|
12
|
+
unsigned_test_apk = File.join(File.dirname(__FILE__), '..','..', 'selendroid-prebuild/selendroid-server.apk')
|
13
|
+
android_platform = Dir["#{ENV["ANDROID_HOME"].gsub("\\", "/")}/platforms/android-*"].last
|
14
|
+
raise "No Android SDK found in #{ENV["ANDROID_HOME"].gsub("\\", "/")}/platforms/" unless android_platform
|
15
|
+
Dir.mktmpdir do |workspace_dir|
|
16
|
+
Dir.chdir(workspace_dir) do
|
17
|
+
FileUtils.cp(unsigned_test_apk, "TestServer.apk")
|
18
|
+
FileUtils.cp(File.join(File.dirname(__FILE__), '..','..', 'selendroid-prebuild/AndroidManifest.xml'), "AndroidManifest.xml")
|
19
|
+
|
20
|
+
unless system %Q{"#{RbConfig.ruby}" -pi.bak -e "gsub(/#targetPackage#/, '#{aut_base_package}')" AndroidManifest.xml}
|
21
|
+
raise "Could not replace package name in manifest"
|
22
|
+
end
|
23
|
+
|
24
|
+
unless system %Q{"#{ENV["ANDROID_HOME"]}/platform-tools/aapt" package -M AndroidManifest.xml -I "#{android_platform}/android.jar" -F dummy.apk}
|
25
|
+
raise "Could not create dummy.apk"
|
26
|
+
end
|
27
|
+
|
28
|
+
Zip::ZipFile.new("dummy.apk").extract("AndroidManifest.xml","customAndroidManifest.xml")
|
29
|
+
Zip::ZipFile.open("TestServer.apk") do |zip_file|
|
30
|
+
zip_file.add("AndroidManifest.xml", "customAndroidManifest.xml")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
sign_apk("#{workspace_dir}/TestServer.apk", test_server_file_name)
|
34
|
+
begin
|
35
|
+
|
36
|
+
rescue Exception => e
|
37
|
+
puts e
|
38
|
+
raise "Could not sign test server"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
puts "Done signing the test server. Moved it to #{test_server_file_name}"
|
42
|
+
end
|
43
|
+
|
44
|
+
def is_windows?
|
45
|
+
(RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/)
|
46
|
+
end
|
47
|
+
|
48
|
+
def sign_apk(app_path, dest_path)
|
49
|
+
if is_windows?
|
50
|
+
jarsigner_path = "\"#{ENV["JAVA_HOME"]}/bin/jarsigner.exe\""
|
51
|
+
else
|
52
|
+
jarsigner_path = "jarsigner"
|
53
|
+
end
|
54
|
+
|
55
|
+
cmd = "#{jarsigner_path} -sigalg MD5withRSA -digestalg SHA1 -signedjar #{dest_path} -storepass android -keystore ~/.android/debug.keystore #{app_path} androiddebugkey"
|
56
|
+
unless system(cmd)
|
57
|
+
puts "jarsigner command: #{cmd}"
|
58
|
+
raise "Could not sign app (#{app_path}"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def selendroid_server_path(base_package)
|
63
|
+
"selendroid-server-#{Selendroid::VERSION}.apk"
|
64
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
2
|
+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
3
|
+
package="org.openqa.selendroid"
|
4
|
+
android:versionCode="1"
|
5
|
+
android:versionName="0.1" >
|
6
|
+
<uses-sdk android:minSdkVersion="16" />
|
7
|
+
|
8
|
+
<instrumentation
|
9
|
+
android:name="org.openqa.selendroid.ServerInstrumentation"
|
10
|
+
android:targetPackage="org.openqa.selendroid.testapp" />
|
11
|
+
|
12
|
+
<uses-permission android:name="android.permission.INTERNET" />
|
13
|
+
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
14
|
+
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />
|
15
|
+
<uses-permission android:name="android.permission.INJECT_EVENTS" />
|
16
|
+
|
17
|
+
<application
|
18
|
+
android:label="Selendroid" >
|
19
|
+
<uses-library android:name="android.test.runner" />
|
20
|
+
</application>
|
21
|
+
|
22
|
+
</manifest>
|
Binary file
|
data/selendroid.gemspec
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require 'selendroid/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |gem|
|
6
|
+
gem.name = "selendroid"
|
7
|
+
gem.platform = Gem::Platform::RUBY
|
8
|
+
gem.version = Selendroid::VERSION
|
9
|
+
gem.authors = ["Dominik Dary"]
|
10
|
+
gem.email = ["ddary@acm.org"]
|
11
|
+
gem.homepage = "http://github.com/DominikDary/"
|
12
|
+
gem.description = %q{Helper to create the selendroid-server}
|
13
|
+
gem.summary = %q{Selendroid Project}
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split("\n") + Dir["selendroid-prebuild"]
|
16
|
+
gem.executables = "selendroid"
|
17
|
+
gem.require_paths = ["lib"]
|
18
|
+
gem.add_dependency( "rubyzip")
|
19
|
+
end
|
metadata
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: selendroid
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
version: 0.1.0
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Dominik Dary
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2013-02-20 00:00:00 +01:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: rubyzip
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 0
|
29
|
+
version: "0"
|
30
|
+
type: :runtime
|
31
|
+
version_requirements: *id001
|
32
|
+
description: Helper to create the selendroid-server
|
33
|
+
email:
|
34
|
+
- ddary@acm.org
|
35
|
+
executables:
|
36
|
+
- selendroid
|
37
|
+
extensions: []
|
38
|
+
|
39
|
+
extra_rdoc_files: []
|
40
|
+
|
41
|
+
files:
|
42
|
+
- .gitignore
|
43
|
+
- Gemfile
|
44
|
+
- LICENSE.txt
|
45
|
+
- README.md
|
46
|
+
- Rakefile
|
47
|
+
- bin/selendroid
|
48
|
+
- lib/selendroid.rb
|
49
|
+
- lib/selendroid/selendroid_builder.rb
|
50
|
+
- lib/selendroid/version.rb
|
51
|
+
- selendroid-prebuild/AndroidManifest.xml
|
52
|
+
- selendroid-prebuild/selendroid-server.apk
|
53
|
+
- selendroid.gemspec
|
54
|
+
has_rdoc: true
|
55
|
+
homepage: http://github.com/DominikDary/
|
56
|
+
licenses: []
|
57
|
+
|
58
|
+
post_install_message:
|
59
|
+
rdoc_options: []
|
60
|
+
|
61
|
+
require_paths:
|
62
|
+
- lib
|
63
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
segments:
|
68
|
+
- 0
|
69
|
+
version: "0"
|
70
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
segments:
|
75
|
+
- 0
|
76
|
+
version: "0"
|
77
|
+
requirements: []
|
78
|
+
|
79
|
+
rubyforge_project:
|
80
|
+
rubygems_version: 1.3.6
|
81
|
+
signing_key:
|
82
|
+
specification_version: 3
|
83
|
+
summary: Selendroid Project
|
84
|
+
test_files: []
|
85
|
+
|