mobproject 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +3 -0
- data/README.md +2 -0
- data/bin/mobproject +5 -0
- data/lib/mobproject.rb +1 -0
- data/lib/mobproject/cli.rb +14 -0
- data/lib/mobproject/generators/project.rb +106 -0
- data/lib/mobproject/generators/project/Gemfile.tt +14 -0
- data/lib/mobproject/generators/project/Rakefile.tt +226 -0
- data/lib/mobproject/generators/project/android.yml.tt +10 -0
- data/lib/mobproject/generators/project/android_devices.yml.tt +10 -0
- data/lib/mobproject/generators/project/android_emulators.yml.tt +3 -0
- data/lib/mobproject/generators/project/android_sauce.yml.tt +8 -0
- data/lib/mobproject/generators/project/base.rb.tt +10 -0
- data/lib/mobproject/generators/project/capabilities.rb.tt +130 -0
- data/lib/mobproject/generators/project/cucumber.yml.tt +15 -0
- data/lib/mobproject/generators/project/env.rb.tt +33 -0
- data/lib/mobproject/generators/project/gitignore.tt +4 -0
- data/lib/mobproject/generators/project/hack.rb.tt +10 -0
- data/lib/mobproject/generators/project/hooks.rb.tt +44 -0
- data/lib/mobproject/generators/project/ios.yml.tt +24 -0
- data/lib/mobproject/generators/project/ios_devices.yml.tt +10 -0
- data/lib/mobproject/generators/project/ios_sauce.yml.tt +19 -0
- data/lib/mobproject/generators/project/ios_simulators.yml.tt +84 -0
- data/lib/mobproject/generators/project/login.rb.tt +38 -0
- data/lib/mobproject/generators/project/mobtest.feature.tt +7 -0
- data/lib/mobproject/generators/project/platforms.rb.tt +15 -0
- data/lib/mobproject/generators/project/step_definitions.rb.tt +7 -0
- data/lib/mobproject/generators/project/utilities.rb.tt +46 -0
- data/mobproject.gemspec +16 -0
- metadata +103 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 3c19b479b727eb5c7a8aa24489f572115677e244
|
4
|
+
data.tar.gz: 057a64d799e2c8e4d33408a7ad3f1852b11037de
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 2c925d5b58c306b02a66c4ff955e9fea72269d75f50aa875e118bb07160a5a6f44ef52fd2771815008d46f6719a23e0c84c66b497adb8f2dfdcc6705ff35f5c3
|
7
|
+
data.tar.gz: 51e83965f6850ad3801ddd050a7f4aa1c6754e35c8c8ac04dbcbafba608ce64a45434da0fb0ba24b92bdc324698fbac4d1cb1d70ad2b72de1c78606f1b45bf83
|
data/.gitignore
ADDED
data/README.md
ADDED
data/bin/mobproject
ADDED
data/lib/mobproject.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'mobproject/cli'
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require_relative '../mobproject/generators/project'
|
3
|
+
|
4
|
+
module MobProject
|
5
|
+
class CLI < Thor
|
6
|
+
|
7
|
+
desc "create <project_name>", "Create a new test project"
|
8
|
+
def create(project_name)
|
9
|
+
puts "...Creating project structure for #{project_name}"
|
10
|
+
MobProject::Generators::Project.start([project_name])
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'thor/group'
|
2
|
+
|
3
|
+
module MobProject
|
4
|
+
module Generators
|
5
|
+
class Project < Thor::Group
|
6
|
+
include Thor::Actions
|
7
|
+
|
8
|
+
argument :name, :type => :string, :desc => 'The name of the project'
|
9
|
+
desc "Generates a project structure for testing with MobTest"
|
10
|
+
|
11
|
+
def self.source_root
|
12
|
+
File.dirname(__FILE__) + "/project"
|
13
|
+
end
|
14
|
+
|
15
|
+
def create_top_directory
|
16
|
+
empty_directory(name)
|
17
|
+
end
|
18
|
+
|
19
|
+
def copy_gitignore
|
20
|
+
template "gitignore.tt", "#{name}/.gitignore"
|
21
|
+
end
|
22
|
+
|
23
|
+
def copy_cucumber_yml
|
24
|
+
template "cucumber.yml.tt", "#{name}/cucumber.yml"
|
25
|
+
end
|
26
|
+
|
27
|
+
def copy_gemfile
|
28
|
+
template "Gemfile.tt", "#{name}/Gemfile"
|
29
|
+
end
|
30
|
+
|
31
|
+
def copy_rakefile
|
32
|
+
copy_file "Rakefile.tt", "#{name}/Rakefile"
|
33
|
+
end
|
34
|
+
|
35
|
+
def copy_hack
|
36
|
+
copy_file 'hack.rb.tt', "#{name}/hack.rb"
|
37
|
+
end
|
38
|
+
|
39
|
+
def create_cucumber_directories
|
40
|
+
empty_directory("#{name}/features")
|
41
|
+
empty_directory("#{name}/features/support")
|
42
|
+
empty_directory("#{name}/features/support/mobile")
|
43
|
+
empty_directory("#{name}/features/support/pages")
|
44
|
+
empty_directory("#{name}/features/support/pages/common")
|
45
|
+
empty_directory("#{name}/features/step_definitions")
|
46
|
+
empty_directory("#{name}/features/support/mobile/platform")
|
47
|
+
empty_directory("#{name}/features/support/mobile/platform/android")
|
48
|
+
empty_directory("#{name}/features/support/mobile/platform/android/inventory")
|
49
|
+
empty_directory("#{name}/features/support/mobile/platform/ios")
|
50
|
+
empty_directory("#{name}/features/support/mobile/platform/ios/inventory")
|
51
|
+
empty_directory("#{name}/features/support/settings")
|
52
|
+
end
|
53
|
+
|
54
|
+
def copy_env
|
55
|
+
template "env.rb.tt", "#{name}/features/support/env.rb"
|
56
|
+
end
|
57
|
+
|
58
|
+
def copy_base
|
59
|
+
template "base.rb.tt", "#{name}/features/support/base.rb"
|
60
|
+
end
|
61
|
+
|
62
|
+
def copy_hooks
|
63
|
+
template "hooks.rb.tt", "#{name}/features/support/hooks.rb"
|
64
|
+
end
|
65
|
+
|
66
|
+
def copy_settings
|
67
|
+
template "android.yml.tt", "#{name}/features/support/settings/android.yml"
|
68
|
+
template "ios.yml.tt", "#{name}/features/support/settings/ios.yml"
|
69
|
+
end
|
70
|
+
|
71
|
+
def copy_utilities
|
72
|
+
template "utilities.rb.tt", "#{name}/features/support/utilities.rb"
|
73
|
+
end
|
74
|
+
|
75
|
+
def copy_step_definitions
|
76
|
+
template "step_definitions.rb.tt", "#{name}/features/step_definitions/step_definitions.rb"
|
77
|
+
end
|
78
|
+
|
79
|
+
def copy_mobtest_feature
|
80
|
+
template "mobtest.feature.tt", "#{name}/features/mobtest.feature"
|
81
|
+
end
|
82
|
+
|
83
|
+
def copy_platforms
|
84
|
+
template "platforms.rb.tt", "#{name}/features/support/mobile/platform/platforms.rb"
|
85
|
+
end
|
86
|
+
|
87
|
+
def copy_capabilities
|
88
|
+
template "capabilities.rb.tt", "#{name}/features/support/mobile/platform/capabilities.rb"
|
89
|
+
end
|
90
|
+
|
91
|
+
def copy_inventory
|
92
|
+
template 'android_devices.yml.tt', "#{name}/features/support/mobile/platform/android/inventory/devices.yml"
|
93
|
+
template 'android_emulators.yml.tt', "#{name}/features/support/mobile/platform/android/inventory/emulators.yml"
|
94
|
+
template 'android_sauce.yml.tt', "#{name}/features/support/mobile/platform/android/inventory/sauce.yml"
|
95
|
+
template 'ios_devices.yml.tt', "#{name}/features/support/mobile/platform/ios/inventory/devices.yml"
|
96
|
+
template 'ios_simulators.yml.tt', "#{name}/features/support/mobile/platform/ios/inventory/simulators.yml"
|
97
|
+
template 'ios_sauce.yml.tt', "#{name}/features/support/mobile/platform/ios/inventory/sauce.yml"
|
98
|
+
end
|
99
|
+
|
100
|
+
def copy_login
|
101
|
+
template "login.rb.tt", "#{name}/features/support/pages/login.rb"
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
source 'http://rubygems.org'
|
2
|
+
|
3
|
+
gem 'cucumber'
|
4
|
+
gem 'rspec'
|
5
|
+
gem 'selenium-webdriver'
|
6
|
+
gem 'bundler'
|
7
|
+
gem 'rake'
|
8
|
+
gem 'appium_lib'
|
9
|
+
gem 'activesupport'
|
10
|
+
gem 'syntax'
|
11
|
+
gem 'rest-client'
|
12
|
+
gem 'mobpage'
|
13
|
+
gem 'sauce_whisk'
|
14
|
+
gem 'mobmanager'
|
@@ -0,0 +1,226 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'cucumber'
|
3
|
+
require 'cucumber/rake/task'
|
4
|
+
require 'rake/task'
|
5
|
+
|
6
|
+
Cucumber::Rake::Task.new(:features) do |t|
|
7
|
+
t.profile = 'default'
|
8
|
+
end
|
9
|
+
|
10
|
+
Cucumber::Rake::Task.new(:api) do |t|
|
11
|
+
t.profile = 'api'
|
12
|
+
end
|
13
|
+
|
14
|
+
task :DEFAULT => :features
|
15
|
+
|
16
|
+
task :web, [:tag, :browser] do |t, args|
|
17
|
+
Cucumber::Rake::Task.new :cucumber_web do |t|
|
18
|
+
ENV['BROWSER'] = args[:browser].to_s.gsub('browser:', '').strip
|
19
|
+
browser = ENV['BROWSER']
|
20
|
+
tag = args[:tag]
|
21
|
+
t.profile = 'web'
|
22
|
+
|
23
|
+
if tag.nil?
|
24
|
+
t.cucumber_opts = html_report_flag("Web_#{browser}")
|
25
|
+
else
|
26
|
+
t.cucumber_opts = "--tags @#{tag.gsub('@', '')} #{html_report_flag("Web_#{browser}")}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
Rake::Task[:cucumber_web].invoke
|
31
|
+
end
|
32
|
+
|
33
|
+
task :android_avd, [:tag, :avd] do |t, args|
|
34
|
+
Cucumber::Rake::Task.new :cucumber_android_avd do |t|
|
35
|
+
ENV['DEVICE'] = args[:avd].to_s.gsub('avd:', '').strip
|
36
|
+
|
37
|
+
emulator = ENV['DEVICE']
|
38
|
+
tag = args[:tag]
|
39
|
+
|
40
|
+
t.profile = 'android_avd'
|
41
|
+
|
42
|
+
if tag.nil?
|
43
|
+
t.cucumber_opts = html_report_flag("Android_#{emulator}")
|
44
|
+
else
|
45
|
+
t.cucumber_opts = "--tags @#{tag.gsub('@', '')} #{html_report_flag("Android_#{emulator}")}"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
Rake::Task[:cucumber_android_avd].invoke
|
50
|
+
end
|
51
|
+
|
52
|
+
task :sauce_android_avd, [:tag, :avd] do |t, args|
|
53
|
+
Cucumber::Rake::Task.new :cucumber_android_avd do |t|
|
54
|
+
test_device_name = args[:avd].to_s.gsub('avd:', '').strip
|
55
|
+
device_info = sauce_emulator_from_yml(test_device_name)
|
56
|
+
|
57
|
+
ENV['DEVICE'] = device_info['name']
|
58
|
+
ENV['VERSION'] = device_info['version']
|
59
|
+
|
60
|
+
tag = args[:tag]
|
61
|
+
|
62
|
+
t.profile = 'sauce_android_avd'
|
63
|
+
|
64
|
+
if tag.nil?
|
65
|
+
t.cucumber_opts = html_report_flag("Sauce_Android_#{test_device_name}")
|
66
|
+
else
|
67
|
+
t.cucumber_opts = "--tags @#{tag.gsub('@', '')} #{html_report_flag("Sauce_Android_#{test_device_name}")}"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
Rake::Task[:cucumber_android_avd].invoke
|
72
|
+
end
|
73
|
+
|
74
|
+
task :ios_simulator, [:tag, :simulator] do |t, args|
|
75
|
+
Cucumber::Rake::Task.new :cucumber_ios_simulator do |t|
|
76
|
+
test_device_name = args[:simulator].to_s.gsub('simulator:', '').strip
|
77
|
+
device_info = ios_simulator_from_yml(test_device_name)
|
78
|
+
ENV['DEVICE'] = device_info['name']
|
79
|
+
ENV['VERSION'] = device_info['version']
|
80
|
+
tag = args[:tag]
|
81
|
+
|
82
|
+
t.profile = 'ios_simulator'
|
83
|
+
|
84
|
+
if tag.nil?
|
85
|
+
t.cucumber_opts = html_report_flag("iOS_#{test_device_name}")
|
86
|
+
else
|
87
|
+
t.cucumber_opts = "--tags @#{tag.gsub('@', '')} #{html_report_flag("iOS_#{test_device_name}")}"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
Rake::Task[:cucumber_ios_simulator].invoke
|
92
|
+
end
|
93
|
+
|
94
|
+
task :sauce_ios_simulator, [:tag, :simulator] do |t, args|
|
95
|
+
Cucumber::Rake::Task.new :cucumber_ios_simulator do |t|
|
96
|
+
test_device_name = args[:simulator].to_s.gsub('simulator:', '').strip
|
97
|
+
device_info = sauce_simulator_from_yml(test_device_name)
|
98
|
+
ENV['DEVICE'] = device_info['name']
|
99
|
+
ENV['VERSION'] = device_info['version']
|
100
|
+
|
101
|
+
tag = args[:tag]
|
102
|
+
|
103
|
+
t.profile = 'sauce_ios_simulator'
|
104
|
+
|
105
|
+
if tag.nil?
|
106
|
+
t.cucumber_opts = html_report_flag("Sauce_iOS_#{test_device_name}")
|
107
|
+
else
|
108
|
+
t.cucumber_opts = "--tags @#{tag.gsub('@', '')} #{html_report_flag("Sauce_iOS_#{test_device_name}")}"
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
Rake::Task[:cucumber_ios_simulator].invoke
|
113
|
+
end
|
114
|
+
|
115
|
+
task :android_avds, [:tag, :devices] do |t, args|
|
116
|
+
$devices = args[:devices]
|
117
|
+
$tag = args[:tag]
|
118
|
+
|
119
|
+
if $devices.to_s.downcase == 'all'
|
120
|
+
devices = all_android_emulators
|
121
|
+
$devices = devices.map { |device| "avd:#{device}" }
|
122
|
+
end
|
123
|
+
|
124
|
+
require_relative 'hack.rb'
|
125
|
+
end
|
126
|
+
|
127
|
+
task :android_device, [:tag, :device] do |t, args|
|
128
|
+
Cucumber::Rake::Task.new :cucumber_android_device do |t|
|
129
|
+
devices = all_android_devices
|
130
|
+
test_device_name = args[:device].to_s.gsub('device:', '').strip
|
131
|
+
device_name = devices.values_at(test_device_name)
|
132
|
+
tag = args[:tag]
|
133
|
+
|
134
|
+
ENV['DEVICE'] = device_name.first
|
135
|
+
|
136
|
+
device = ENV['DEVICE']
|
137
|
+
|
138
|
+
t.profile = 'android_device'
|
139
|
+
|
140
|
+
if tag.nil?
|
141
|
+
t.cucumber_opts = html_report_flag("Android_#{device}")
|
142
|
+
else
|
143
|
+
t.cucumber_opts = "--tags @#{tag.gsub('@', '')} #{html_report_flag("Android_#{device}")}"
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
Rake::Task[:cucumber_android_device].invoke
|
148
|
+
end
|
149
|
+
|
150
|
+
|
151
|
+
def create_directory(path, dir_name)
|
152
|
+
dir = "#{path}/#{dir_name}"
|
153
|
+
Dir.mkdir(path) unless Dir.exist? path
|
154
|
+
Dir.mkdir(dir) unless Dir.exist? dir
|
155
|
+
end
|
156
|
+
|
157
|
+
def all_android_emulators
|
158
|
+
require 'yaml'
|
159
|
+
|
160
|
+
YAML.load_file(Dir.pwd + '/features/support/mobile/platform/android/inventory/emulators.yml')
|
161
|
+
end
|
162
|
+
|
163
|
+
def all_android_devices
|
164
|
+
require 'yaml'
|
165
|
+
|
166
|
+
YAML.load_file(Dir.pwd + '/features/support/mobile/platform/android/inventory/devices.yml')
|
167
|
+
end
|
168
|
+
|
169
|
+
def ios_device_from_yml(name)
|
170
|
+
require 'yaml'
|
171
|
+
|
172
|
+
devices = YAML.load_file(Dir.pwd + '/features/support/mobile/platform/ios/inventory/devices.yml')
|
173
|
+
devices[name]
|
174
|
+
end
|
175
|
+
|
176
|
+
def ios_simulator_from_yml(name)
|
177
|
+
require 'yaml'
|
178
|
+
|
179
|
+
simulators = YAML.load_file(Dir.pwd + '/features/support/mobile/platform/ios/inventory/simulators.yml')
|
180
|
+
simulators[name]
|
181
|
+
end
|
182
|
+
|
183
|
+
def sauce_emulator_from_yml(name)
|
184
|
+
require 'yaml'
|
185
|
+
|
186
|
+
emulators = YAML.load_file(Dir.pwd + '/features/support/mobile/platform/android/inventory/sauce.yml')
|
187
|
+
emulators[name]
|
188
|
+
end
|
189
|
+
|
190
|
+
def sauce_simulator_from_yml(name)
|
191
|
+
require 'yaml'
|
192
|
+
|
193
|
+
emulators = YAML.load_file(Dir.pwd + '/features/support/mobile/platform/ios/inventory/sauce.yml')
|
194
|
+
emulators[name]
|
195
|
+
end
|
196
|
+
|
197
|
+
def android_device_from_yml(name)
|
198
|
+
require 'yaml'
|
199
|
+
|
200
|
+
YAML.load_file(Dir.pwd + '/features/support/mobile/platform/android/inventory/devices.yml')[name]
|
201
|
+
end
|
202
|
+
|
203
|
+
def path_to_results_folder
|
204
|
+
"#{Dir.pwd}/features/results"
|
205
|
+
end
|
206
|
+
|
207
|
+
def date_folder
|
208
|
+
dt = Time.new
|
209
|
+
|
210
|
+
"#{dt.year}#{dt.month}#{dt.day}"
|
211
|
+
end
|
212
|
+
|
213
|
+
def unique_postfix
|
214
|
+
dt = Time.new
|
215
|
+
|
216
|
+
"#{dt.hour}_#{dt.min}_#{dt.sec}"
|
217
|
+
end
|
218
|
+
|
219
|
+
def html_report_flag(name)
|
220
|
+
path = path_to_results_folder
|
221
|
+
date_dir = date_folder
|
222
|
+
uniq_postfix = unique_postfix
|
223
|
+
create_directory(path, date_dir)
|
224
|
+
report_name = "#{name}__#{uniq_postfix}.html"
|
225
|
+
"-f html --out #{path}/#{date_dir}/#{report_name}"
|
226
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
#TODO - look into building .apk on the fly
|
2
|
+
#:apk: 'YOUR ANDROID APPLICATION PACKAGE'
|
3
|
+
#:apk_path: 'PATH TO YOUR ANDROID APK'
|
4
|
+
#:android_package: "YOUR APPLICATION'S PACKAGE"
|
5
|
+
#:android_activity: "YOUR APPLICATION'S MAIN ACTIVITY"
|
6
|
+
#E.G.:
|
7
|
+
#:apk: 'app-STATION-debug-unaligned.apk'
|
8
|
+
#:apk_path: '/Users/you/Downloads/app-STATION-debug-unaligned.apk'
|
9
|
+
#:android_package: 'com.media.news.station'
|
10
|
+
#:android_activity: 'com.mob.media.app.SplashActivity'
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# Keep a list of physical devices
|
2
|
+
# <DEVICE_NAME>:<DEVICE ID>
|
3
|
+
# Give your devices a meaningful name. A name that could easily tell the device type and os
|
4
|
+
# The device name will be passed to a rake task(s) for execution.
|
5
|
+
# You can get your device id by plugging your device via USB and running the command 'adb devices' on your terminal.
|
6
|
+
# Your device may need to be setup for development.
|
7
|
+
|
8
|
+
# For example:
|
9
|
+
# samsung_s5_kitkat_442: 102448dd
|
10
|
+
# droid_maxx_kitkat_444: TA96106AQK
|
@@ -0,0 +1,130 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'appium_lib'
|
3
|
+
require_relative '../../utilities'
|
4
|
+
|
5
|
+
module Platform
|
6
|
+
module Capabilities
|
7
|
+
|
8
|
+
include Utils
|
9
|
+
|
10
|
+
def setup_ios
|
11
|
+
if ENV['TARGET'] == 'sauce'
|
12
|
+
capabilities = sauce_ios_capabilities
|
13
|
+
else
|
14
|
+
capabilities = {caps: ios_capabilities}
|
15
|
+
end
|
16
|
+
Appium::Driver.new(capabilities).start_driver
|
17
|
+
end
|
18
|
+
|
19
|
+
def setup_android
|
20
|
+
if ENV['TARGET'] == 'sauce'
|
21
|
+
capabilities = sauce_android_capabilities
|
22
|
+
else
|
23
|
+
capabilities = {caps: android_capabilities}
|
24
|
+
puts 'Setting android package ' + capabilities[:caps][:appPackage]
|
25
|
+
end
|
26
|
+
Appium::Driver.new(capabilities).start_driver
|
27
|
+
end
|
28
|
+
|
29
|
+
def setup_web
|
30
|
+
browser = ENV['BROWSER']
|
31
|
+
Selenium::WebDriver.for browser.to_sym
|
32
|
+
end
|
33
|
+
|
34
|
+
def android_capabilities
|
35
|
+
caps = android_settings
|
36
|
+
|
37
|
+
capabilities =
|
38
|
+
{
|
39
|
+
platformName: 'Android',
|
40
|
+
app: caps[:apk_path],
|
41
|
+
appPackage: caps[:android_package],
|
42
|
+
appActivity: caps[:app_activity]
|
43
|
+
}
|
44
|
+
if ENV['ANDROID_PHONE'] == 'emulator'
|
45
|
+
capabilities = capabilities.merge(deviceName: 'Android Emulator', avd: ENV['DEVICE'])
|
46
|
+
else
|
47
|
+
capabilities = capabilities.merge(deviceName: ENV['DEVICE'])
|
48
|
+
end
|
49
|
+
|
50
|
+
capabilities
|
51
|
+
end
|
52
|
+
|
53
|
+
def sauce_android_capabilities
|
54
|
+
cap = android_settings
|
55
|
+
app = cap[:apk_path].split('/').select{|element| element.include?'.apk'}.first
|
56
|
+
sauce_user = %x[echo $SAUCE_USER].strip
|
57
|
+
sauce_key = %x[echo $SAUCE_KEY].strip
|
58
|
+
{
|
59
|
+
caps: {
|
60
|
+
platformName: 'Android',
|
61
|
+
app: cap[:apk_path],
|
62
|
+
appPackage: cap[:android_package],
|
63
|
+
appActivity: cap[:android_activity],
|
64
|
+
:'appium-version' => '1.3.7',
|
65
|
+
platformVersion: ENV['VERSION'],
|
66
|
+
deviceName: ENV['DEVICE'],
|
67
|
+
app: 'sauce-storage:'+app,
|
68
|
+
name: app,
|
69
|
+
:'access-key' => sauce_key
|
70
|
+
},
|
71
|
+
appium_lib: {
|
72
|
+
wait: 15,
|
73
|
+
server_url: "http://#{sauce_user}:#{sauce_key}@ondemand.saucelabs.com:80/wd/hub",
|
74
|
+
sauce_username: sauce_user,
|
75
|
+
sauce_access_key: sauce_key
|
76
|
+
}
|
77
|
+
}
|
78
|
+
end
|
79
|
+
|
80
|
+
def ios_capabilities
|
81
|
+
caps = ios_settings
|
82
|
+
caps[:app_path] = ENV['IOS_DERIVED_DATA_PATH']+ '/' + caps[:app] if caps[:app_path].nil?
|
83
|
+
|
84
|
+
capabilities =
|
85
|
+
{
|
86
|
+
deviceName: ENV['DEVICE'],
|
87
|
+
platformVersion: ENV['VERSION'],
|
88
|
+
platformName: 'iOS',
|
89
|
+
preLaunch: true,
|
90
|
+
app: caps[:app_path]
|
91
|
+
}
|
92
|
+
if ENV['IOS_PHONE'] == 'device'
|
93
|
+
capabilities.merge!(uiud: ENV['UIUD'], bundleId: caps[:bundle_id])
|
94
|
+
end
|
95
|
+
|
96
|
+
capabilities
|
97
|
+
end
|
98
|
+
|
99
|
+
def sauce_ios_capabilities
|
100
|
+
cap = ios_settings
|
101
|
+
cap[:app_path] = ENV['IOS_DERIVED_DATA_PATH']+'/'+cap[:app] if cap[:app_path].nil?
|
102
|
+
|
103
|
+
sauce_user = %x[echo $SAUCE_USER].strip
|
104
|
+
sauce_key = %x[echo $SAUCE_KEY].strip
|
105
|
+
app = cap[:app_path].split('/').select{|element| element.include?'.app'}.first.gsub('.app','.zip')
|
106
|
+
{
|
107
|
+
caps: {
|
108
|
+
platformName: 'iOS',
|
109
|
+
:'appium-version' => '1.3.7',
|
110
|
+
platformVersion: ENV['VERSION'],
|
111
|
+
deviceName: 'iPhone 6',
|
112
|
+
app: "sauce-storage:#{app}",
|
113
|
+
:'access-key' => sauce_key,
|
114
|
+
name: app
|
115
|
+
},
|
116
|
+
appium_lib: {
|
117
|
+
wait: 15,
|
118
|
+
server_url: "http://#{sauce_user}:#{sauce_key}@ondemand.saucelabs.com:80/wd/hub",
|
119
|
+
sauce_username: sauce_user,
|
120
|
+
sauce_access_key: sauce_key
|
121
|
+
}
|
122
|
+
}
|
123
|
+
end
|
124
|
+
|
125
|
+
def start_selenium_driver
|
126
|
+
self.send("setup_#{ENV['PLATFORM']}")
|
127
|
+
end
|
128
|
+
|
129
|
+
end
|
130
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
default: --no-source --color --format pretty PLATFORM=android ANDROID_PHONE=emulator TARGET=local_android_emulator --tags ~@ignore --tags ~@wip
|
2
|
+
|
3
|
+
api: --no-source --color --format pretty PLATFORM=android API_TEST=true --tags ~@ignore --tags @api
|
4
|
+
|
5
|
+
android_avd: --no-source --color --format pretty PLATFORM=android ANDROID_PHONE=emulator TARGET=local_android_emulator --tags ~@ignore --tags ~@wip --tags ~android_quarantine
|
6
|
+
|
7
|
+
sauce_android_avd: --no-source --color --format pretty PLATFORM=android ANDROID_PHONE=emulator TARGET=sauce --tags ~@ignore --tags ~@wip --tags ~android_quarantine
|
8
|
+
|
9
|
+
android_device: --no-source --color --format pretty PLATFORM=android ANDROID_PHONE=device TARGET=local_android_device --tags ~@ignore --tags ~@wip --tags ~android_quarantine
|
10
|
+
|
11
|
+
ios_simulator: --no-source --color --format pretty PLATFORM=ios IOS_PHONE=simulator TARGET=local_android_device --tags ~@ignore --tags ~@wip --tags ~ios_quarantine
|
12
|
+
|
13
|
+
sauce_ios_simulator: --no-source --color --format pretty PLATFORM=ios IOS_PHONE=simulator TARGET=sauce --tags ~@ignore --tags ~@wip --tags ~ios_quarantine
|
14
|
+
|
15
|
+
web: --no-source --color --format pretty PLATFORM=web TARGET=web --tags ~@ignore --tags ~@wip
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
require 'active_support/all'
|
3
|
+
require 'mobpage'
|
4
|
+
require 'mobmanager'
|
5
|
+
|
6
|
+
require_relative '../support/mobile/platform/capabilities'
|
7
|
+
require_relative '../support/mobile/platform/platforms'
|
8
|
+
require_relative 'utilities'
|
9
|
+
require_relative 'base'
|
10
|
+
|
11
|
+
include Platform::Capabilities
|
12
|
+
include Mobile::Appium::Server
|
13
|
+
include Platform::Android::Common
|
14
|
+
include Platform::IOS::Common
|
15
|
+
include Mobile::Platform
|
16
|
+
include Utils
|
17
|
+
include MobTest
|
18
|
+
extend Mobile::Platform
|
19
|
+
|
20
|
+
ENV['IOS_DERIVED_DATA_PATH'] = '~/Build/Products/Debug-iphonesimulator'
|
21
|
+
|
22
|
+
android do
|
23
|
+
start_appium_server unless ENV['TARGET'] == 'sauce'
|
24
|
+
prepare_android_phone(android_settings)
|
25
|
+
end unless ENV['TARGET'] == 'web'
|
26
|
+
|
27
|
+
ios do
|
28
|
+
start_appium_server unless ENV['TARGET'] == 'sauce'
|
29
|
+
prepare_ios_phone(ios_settings)
|
30
|
+
end unless ENV['TARGET'] == 'web'
|
31
|
+
|
32
|
+
World(PageObject::Navigation)
|
33
|
+
World(Utils)
|
@@ -0,0 +1,10 @@
|
|
1
|
+
#TODO - Needs work
|
2
|
+
# This hack is use to iterate through scenarios to work around some of cucumber limitations
|
3
|
+
devices = $devices
|
4
|
+
puts "list of devices #{devices}"
|
5
|
+
devices = devices.to_s.split('avd:').select { |dvc| dvc != '' } if devices.kind_of?(String)
|
6
|
+
|
7
|
+
devices.each do |device|
|
8
|
+
puts "device #{device}"
|
9
|
+
system "rake android_avd['@#{$tag}','avd:#{device}']"
|
10
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'selenium-webdriver'
|
2
|
+
require 'appium_lib'
|
3
|
+
|
4
|
+
driver = start_selenium_driver
|
5
|
+
|
6
|
+
bool_status = false
|
7
|
+
|
8
|
+
Before do
|
9
|
+
@driver = driver
|
10
|
+
end
|
11
|
+
|
12
|
+
After do |scenario|
|
13
|
+
if scenario.passed?
|
14
|
+
bool_status = true
|
15
|
+
end
|
16
|
+
|
17
|
+
if scenario.failed?
|
18
|
+
take_screenshot(scenario, @driver)
|
19
|
+
# TODO: close_all_windows_except_main(@driver) if ENV['PLATFORM'] == 'web'
|
20
|
+
end
|
21
|
+
|
22
|
+
@driver.reset unless ENV['TARGET'] == 'web'
|
23
|
+
end
|
24
|
+
|
25
|
+
at_exit do
|
26
|
+
if ENV['TARGET'] != 'sauce' && ENV['TARGET'] != 'web'
|
27
|
+
system "adb shell pm uninstall -k #{android_settings[:android_package]}" if ENV['PLATFORM'] == 'android'
|
28
|
+
terminate_simulator if ENV['PLATFORM'] == 'ios'
|
29
|
+
puts 'Terminated appium server session'
|
30
|
+
system 'pkill node'
|
31
|
+
else
|
32
|
+
if ENV['TARGET'] == 'web'
|
33
|
+
driver.quit
|
34
|
+
else
|
35
|
+
require 'sauce_whisk'
|
36
|
+
|
37
|
+
ENV['SAUCE_USERNAME'] = %x[echo $SAUCE_USER].strip
|
38
|
+
ENV['SAUCE_ACCESS_KEY'] = %x[echo $SAUCE_KEY].strip
|
39
|
+
|
40
|
+
SauceWhisk::Jobs.change_status $driver.driver.session_id, bool_status
|
41
|
+
driver.quit
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
#=============================================================
|
2
|
+
#IF YOU WISH TO HAVE MOBTEST BUILD YOUR APP PROVIDE:
|
3
|
+
#=============================================================
|
4
|
+
#workspace_path: 'THE PATH TO YOUR XCODE PROJECT WORKSPACE'
|
5
|
+
#app: 'THEN NAME OF YOUR APPLICATION AS A .APP FILE'
|
6
|
+
#app_path: ~
|
7
|
+
#sim_sdk: 'SIMULATOR SDK VERSION'
|
8
|
+
#E.G
|
9
|
+
#:workspace_path: '~/Projects/MediaiOS/Media.xcworkspace'
|
10
|
+
#:app: 'STATION.app'
|
11
|
+
#:app_path: ~
|
12
|
+
#:sim_sdk: 'iphonesimulator8.4'
|
13
|
+
|
14
|
+
#======================================================================
|
15
|
+
#IF YOU WISH TO TEST YOUR OWN COMPILED IOS APP ON A SIMULATOR PROVIDE:
|
16
|
+
#======================================================================
|
17
|
+
#:app_path: 'PATH TO YOUR .APP FILE'
|
18
|
+
#E.G.:
|
19
|
+
#:app_path: '~/Build/Products/Debug-iphonesimulator/STATION.app'
|
20
|
+
|
21
|
+
#=============================================================
|
22
|
+
#TODO - IF YOU WISH TO TEST ON A PHYSICAL DEVICE PROVIDE:
|
23
|
+
#=============================================================
|
24
|
+
#:bundle_id: 'YOUR BUNDLE ID'
|
@@ -0,0 +1,19 @@
|
|
1
|
+
iphone_6_8.3:
|
2
|
+
name: iPhone 6
|
3
|
+
version: '8.3'
|
4
|
+
|
5
|
+
iphone_6_plus_8.3:
|
6
|
+
name: iPhone 6 Plus
|
7
|
+
version: '8.3'
|
8
|
+
|
9
|
+
iphone_6_8.3:
|
10
|
+
name: iPhone 6
|
11
|
+
version: '8.3'
|
12
|
+
|
13
|
+
iphone_6_plus_8.4:
|
14
|
+
name: iPhone 6 Plus
|
15
|
+
version: '8.4'
|
16
|
+
|
17
|
+
iphone_simulator_7.1:
|
18
|
+
name: iPhone Simulator
|
19
|
+
version: '7.1'
|
@@ -0,0 +1,84 @@
|
|
1
|
+
#THIS WILL DEPEND ON YOUR SDK VERSION:
|
2
|
+
resizable_ipad_8.1:
|
3
|
+
name: Resizable iPad
|
4
|
+
version: '8.1'
|
5
|
+
|
6
|
+
resizable_ipad_8.3:
|
7
|
+
name: Resizable iPad
|
8
|
+
version: '8.3'
|
9
|
+
|
10
|
+
resizable_iphone_8.1:
|
11
|
+
name: Resizable iPhone
|
12
|
+
version: '8.1'
|
13
|
+
|
14
|
+
resizable_iphone_8.3:
|
15
|
+
name: Resizable iPhone
|
16
|
+
version: '8.3'
|
17
|
+
|
18
|
+
ipad_2_8.1:
|
19
|
+
name: iPad 2
|
20
|
+
version: '8.1'
|
21
|
+
|
22
|
+
ipad_2_8.3:
|
23
|
+
name: iPad 2
|
24
|
+
version: '8.3'
|
25
|
+
|
26
|
+
ipad_air_8.1:
|
27
|
+
name: iPad Air
|
28
|
+
version: '8.1'
|
29
|
+
ipad_air_8.3:
|
30
|
+
name: iPad Air
|
31
|
+
version: '8.3'
|
32
|
+
|
33
|
+
ipad_retina_8.1:
|
34
|
+
name: iPad Retina
|
35
|
+
version: '8.1'
|
36
|
+
|
37
|
+
ipad_retina_8.3:
|
38
|
+
name: iPad Retina
|
39
|
+
version: '8.3'
|
40
|
+
|
41
|
+
ipad_iphone_4s_8.1:
|
42
|
+
name: iPhone 4s
|
43
|
+
version: '8.1'
|
44
|
+
|
45
|
+
ipad_iphone_4s_8.3:
|
46
|
+
name: iPhone 4s
|
47
|
+
version: '8.3'
|
48
|
+
|
49
|
+
iphone_5_8.1:
|
50
|
+
name: iPhone 5
|
51
|
+
version: '8.1'
|
52
|
+
|
53
|
+
iphone_5_8.3:
|
54
|
+
name: iPhone 5
|
55
|
+
version: '8.3'
|
56
|
+
|
57
|
+
iphone_5s_8.1:
|
58
|
+
name: iPhone 5s
|
59
|
+
version: '8.1'
|
60
|
+
|
61
|
+
iphone_5s_8.3:
|
62
|
+
name: iPhone 5s
|
63
|
+
version: '8.3'
|
64
|
+
|
65
|
+
iphone_6_8.1:
|
66
|
+
name: iPhone 6
|
67
|
+
version: '8.1'
|
68
|
+
|
69
|
+
iphone_6_8.3:
|
70
|
+
name: iPhone 6
|
71
|
+
version: '8.3'
|
72
|
+
|
73
|
+
iphone_6_plus_8.1:
|
74
|
+
name: iPhone 6 Plus
|
75
|
+
version: '8.1'
|
76
|
+
|
77
|
+
iphone_6_plus_8.3:
|
78
|
+
name: iPhone 6 Plus
|
79
|
+
version: '8.3'
|
80
|
+
|
81
|
+
iphone_5_7.1:
|
82
|
+
name: iPhone 5s
|
83
|
+
version: '7.1'
|
84
|
+
|
@@ -0,0 +1,38 @@
|
|
1
|
+
#------------------------------------------------------------------
|
2
|
+
# FOLLOW THE BELLOW EXAMPLE TO CREATE YOUR PAGE OBJECT CLASSES
|
3
|
+
#------------------------------------------------------------------
|
4
|
+
|
5
|
+
class Login < MobTest::Base
|
6
|
+
|
7
|
+
ios do
|
8
|
+
text_field(:username, name: 'username')
|
9
|
+
text_field(:password, name: 'password')
|
10
|
+
button(:login, name: 'login')
|
11
|
+
end
|
12
|
+
|
13
|
+
android do
|
14
|
+
text_field(:username, id: 'android:id/username')
|
15
|
+
text_field(:password, id: 'android:id/password')
|
16
|
+
button(:login, id: 'android:id/login')
|
17
|
+
end
|
18
|
+
|
19
|
+
web do
|
20
|
+
text_field(:username, id: 'username')
|
21
|
+
text_field(:password, name: 'password')
|
22
|
+
button(:login, name: 'login')
|
23
|
+
end
|
24
|
+
|
25
|
+
ios do
|
26
|
+
#place your ios specific methods within this block
|
27
|
+
end
|
28
|
+
|
29
|
+
android do
|
30
|
+
#place your android specific methods within this block
|
31
|
+
end
|
32
|
+
|
33
|
+
web do
|
34
|
+
#place your web specific methods within this block
|
35
|
+
end
|
36
|
+
|
37
|
+
#place methods that apply to all platforms outside the blocks
|
38
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Mobile
|
2
|
+
module Platform
|
3
|
+
def android(&block)
|
4
|
+
yield block if ENV['PLATFORM'] == 'android'
|
5
|
+
end
|
6
|
+
|
7
|
+
def ios(&block)
|
8
|
+
yield block if ENV['PLATFORM'] == 'ios'
|
9
|
+
end
|
10
|
+
|
11
|
+
def web(&block)
|
12
|
+
yield block if ENV['PLATFORM'] == 'web'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Utils
|
2
|
+
def take_screenshot(scenario, driver)
|
3
|
+
dt = Time.new
|
4
|
+
path = "#{Dir.pwd}/features/results"
|
5
|
+
date_dir = "#{dt.year}#{dt.month}#{dt.day}"
|
6
|
+
create_directory(path, date_dir)
|
7
|
+
screenshot_name = "#{ENV['PLATFORM']}_#{ENV['DEVICE']}_#{scenario.name.gsub(' ', '_').gsub(/[^0-9A-Za-z_]/, '')}_#{dt.hour}_#{dt.min}_#{dt.sec}.png"
|
8
|
+
screenshot = Dir.pwd + '/features/results/' + date_dir + '/' + screenshot_name
|
9
|
+
save_and_embed_image(screenshot, driver)
|
10
|
+
end
|
11
|
+
|
12
|
+
def save_screenshot_locally(name, driver)
|
13
|
+
dt = Time.new
|
14
|
+
screenshot_name = "#{name}_#{dt.day}_#{dt.hour}_#{dt.min}_#{dt.sec}.png"
|
15
|
+
dir = Dir.home + '/Screenshots'
|
16
|
+
Dir.mkdir(dir) unless Dir.exist?(dir)
|
17
|
+
screenshot = dir + '/' + screenshot_name
|
18
|
+
driver.save_screenshot(screenshot)
|
19
|
+
end
|
20
|
+
|
21
|
+
def create_directory(path, dir_name)
|
22
|
+
dir = "#{path}/#{dir_name}"
|
23
|
+
Dir.mkdir(path) unless Dir.exist? path
|
24
|
+
Dir.mkdir(dir) unless Dir.exist? dir
|
25
|
+
end
|
26
|
+
|
27
|
+
def email_results
|
28
|
+
#TODO
|
29
|
+
end
|
30
|
+
|
31
|
+
def ios_settings
|
32
|
+
setup = YAML.load_file(Dir.pwd + '/features/support/settings/ios.yml')
|
33
|
+
setup[:app_path] = ENV['IOS_DERIVED_DATA_PATH']+'/'+setup[:app] if setup[:app_path].nil?
|
34
|
+
setup
|
35
|
+
end
|
36
|
+
|
37
|
+
def android_settings
|
38
|
+
YAML.load_file(Dir.pwd + '/features/support/settings/android.yml')
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
def save_and_embed_image(path, driver)
|
43
|
+
driver.save_screenshot(path)
|
44
|
+
embed(path, "image/png")
|
45
|
+
end
|
46
|
+
end
|
data/mobproject.gemspec
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'mobproject'
|
3
|
+
s.version = '0.0.1'
|
4
|
+
s.date = '2015-12-08'
|
5
|
+
s.summary = 'Creates a project directory to test mobile and web applications with Appium/Selenium and Cucumber'
|
6
|
+
s.description = 'Creates a project directory test iOS, Android mobile and Web applications with Appium/Selenium and Cucumber'
|
7
|
+
s.authors = ['Milton Davalos']
|
8
|
+
s.email = 'miltondavalos@gmail.com'
|
9
|
+
s.homepage = 'https://github.com/miltondavalos/MobProject'
|
10
|
+
s.license = 'MIT'
|
11
|
+
s.files = `git ls-files`.split("\n")
|
12
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
13
|
+
s.require_paths = ["lib"]
|
14
|
+
s.add_dependency 'require_all'
|
15
|
+
s.add_dependency 'thor'
|
16
|
+
end
|
metadata
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mobproject
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Milton Davalos
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-12-08 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: require_all
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: thor
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
description: Creates a project directory test iOS, Android mobile and Web applications
|
42
|
+
with Appium/Selenium and Cucumber
|
43
|
+
email: miltondavalos@gmail.com
|
44
|
+
executables:
|
45
|
+
- mobproject
|
46
|
+
extensions: []
|
47
|
+
extra_rdoc_files: []
|
48
|
+
files:
|
49
|
+
- .gitignore
|
50
|
+
- README.md
|
51
|
+
- bin/mobproject
|
52
|
+
- lib/mobproject.rb
|
53
|
+
- lib/mobproject/cli.rb
|
54
|
+
- lib/mobproject/generators/project.rb
|
55
|
+
- lib/mobproject/generators/project/Gemfile.tt
|
56
|
+
- lib/mobproject/generators/project/Rakefile.tt
|
57
|
+
- lib/mobproject/generators/project/android.yml.tt
|
58
|
+
- lib/mobproject/generators/project/android_devices.yml.tt
|
59
|
+
- lib/mobproject/generators/project/android_emulators.yml.tt
|
60
|
+
- lib/mobproject/generators/project/android_sauce.yml.tt
|
61
|
+
- lib/mobproject/generators/project/base.rb.tt
|
62
|
+
- lib/mobproject/generators/project/capabilities.rb.tt
|
63
|
+
- lib/mobproject/generators/project/cucumber.yml.tt
|
64
|
+
- lib/mobproject/generators/project/env.rb.tt
|
65
|
+
- lib/mobproject/generators/project/gitignore.tt
|
66
|
+
- lib/mobproject/generators/project/hack.rb.tt
|
67
|
+
- lib/mobproject/generators/project/hooks.rb.tt
|
68
|
+
- lib/mobproject/generators/project/ios.yml.tt
|
69
|
+
- lib/mobproject/generators/project/ios_devices.yml.tt
|
70
|
+
- lib/mobproject/generators/project/ios_sauce.yml.tt
|
71
|
+
- lib/mobproject/generators/project/ios_simulators.yml.tt
|
72
|
+
- lib/mobproject/generators/project/login.rb.tt
|
73
|
+
- lib/mobproject/generators/project/mobtest.feature.tt
|
74
|
+
- lib/mobproject/generators/project/platforms.rb.tt
|
75
|
+
- lib/mobproject/generators/project/step_definitions.rb.tt
|
76
|
+
- lib/mobproject/generators/project/utilities.rb.tt
|
77
|
+
- mobproject.gemspec
|
78
|
+
homepage: https://github.com/miltondavalos/MobProject
|
79
|
+
licenses:
|
80
|
+
- MIT
|
81
|
+
metadata: {}
|
82
|
+
post_install_message:
|
83
|
+
rdoc_options: []
|
84
|
+
require_paths:
|
85
|
+
- lib
|
86
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - '>='
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - '>='
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
96
|
+
requirements: []
|
97
|
+
rubyforge_project:
|
98
|
+
rubygems_version: 2.0.14
|
99
|
+
signing_key:
|
100
|
+
specification_version: 4
|
101
|
+
summary: Creates a project directory to test mobile and web applications with Appium/Selenium
|
102
|
+
and Cucumber
|
103
|
+
test_files: []
|