mobproject 0.0.1
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.
- 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: []
|