mobproject 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (31) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +3 -0
  3. data/README.md +2 -0
  4. data/bin/mobproject +5 -0
  5. data/lib/mobproject.rb +1 -0
  6. data/lib/mobproject/cli.rb +14 -0
  7. data/lib/mobproject/generators/project.rb +106 -0
  8. data/lib/mobproject/generators/project/Gemfile.tt +14 -0
  9. data/lib/mobproject/generators/project/Rakefile.tt +226 -0
  10. data/lib/mobproject/generators/project/android.yml.tt +10 -0
  11. data/lib/mobproject/generators/project/android_devices.yml.tt +10 -0
  12. data/lib/mobproject/generators/project/android_emulators.yml.tt +3 -0
  13. data/lib/mobproject/generators/project/android_sauce.yml.tt +8 -0
  14. data/lib/mobproject/generators/project/base.rb.tt +10 -0
  15. data/lib/mobproject/generators/project/capabilities.rb.tt +130 -0
  16. data/lib/mobproject/generators/project/cucumber.yml.tt +15 -0
  17. data/lib/mobproject/generators/project/env.rb.tt +33 -0
  18. data/lib/mobproject/generators/project/gitignore.tt +4 -0
  19. data/lib/mobproject/generators/project/hack.rb.tt +10 -0
  20. data/lib/mobproject/generators/project/hooks.rb.tt +44 -0
  21. data/lib/mobproject/generators/project/ios.yml.tt +24 -0
  22. data/lib/mobproject/generators/project/ios_devices.yml.tt +10 -0
  23. data/lib/mobproject/generators/project/ios_sauce.yml.tt +19 -0
  24. data/lib/mobproject/generators/project/ios_simulators.yml.tt +84 -0
  25. data/lib/mobproject/generators/project/login.rb.tt +38 -0
  26. data/lib/mobproject/generators/project/mobtest.feature.tt +7 -0
  27. data/lib/mobproject/generators/project/platforms.rb.tt +15 -0
  28. data/lib/mobproject/generators/project/step_definitions.rb.tt +7 -0
  29. data/lib/mobproject/generators/project/utilities.rb.tt +46 -0
  30. data/mobproject.gemspec +16 -0
  31. 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
@@ -0,0 +1,3 @@
1
+ .DS_Store
2
+ .idea/
3
+ *.gem
data/README.md ADDED
@@ -0,0 +1,2 @@
1
+ # MobProject
2
+ CLI gem to create project structure
data/bin/mobproject ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative '../lib/mobproject/cli'
4
+
5
+ MobProject::CLI.start
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,3 @@
1
+ # YOU NEED TO CREATE YOUR ADV
2
+ # E.G.:
3
+ #- nexus_5_lollipop
@@ -0,0 +1,8 @@
1
+ #ADD DEVICES AS YOU NEED THEM. CHECK LIST OF DEVICES ON SAUCELABS SITE
2
+ nexus_7_hd_4.4:
3
+ name: Google Nexus 7 HD Emulator
4
+ version: '4.4'
5
+
6
+ galaxy_s4_4.3:
7
+ name: Samsung Galaxy S4 Emulator
8
+ version: '4.3'
@@ -0,0 +1,10 @@
1
+ module MobTest
2
+ class Base
3
+ extend Mobile::Platform
4
+ extend PageObject::Accessors
5
+
6
+ def initialize(selenium_driver)
7
+ @driver = selenium_driver
8
+ end
9
+ end
10
+ end
@@ -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,4 @@
1
+ /Gemfile.lock
2
+ /features/results
3
+ .idea
4
+ .DS_Store
@@ -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,10 @@
1
+ #ADD YOUR OWN DEVICES
2
+ #E.G.:
3
+ #iphone_4_8.1:
4
+ # name: iPhone 4
5
+ # uiud: 5de2ba8d57e51690b0f6a226e090f14d44bc4302
6
+ # version: '8.1'
7
+ #
8
+ #iphone_5s_8.1:
9
+ # uiud: 5de2ba8d57e51690b0f6a226e090f14d44bc4xxx302
10
+ # version: '8.1x'
@@ -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,7 @@
1
+ Feature: MobTest setup
2
+ As a user I want to verify my framework works
3
+
4
+ @mobtest
5
+ Scenario: Start Application and take screenshot
6
+ Given Application is up and running
7
+ Then I take a screenshot and save it to ~/Screenshots
@@ -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,7 @@
1
+ Given(/^Application is up and running$/) do
2
+ sleep 10
3
+ end
4
+
5
+ Then(/^I take a screenshot and save it to ~\/Screenshots$/) do
6
+ save_screenshot_locally("MobTest_#{ENV['PLATFORM']}", @driver)
7
+ 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
@@ -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: []