sunomono 0.2.0.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/Gemfile +9 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +157 -0
  6. data/Rakefile +1 -0
  7. data/bin/suno +3 -0
  8. data/bin/sunomono +3 -0
  9. data/lib/aws/android/app_installation_hooks.rb +30 -0
  10. data/lib/aws/android/app_life_cycle_hooks.rb +13 -0
  11. data/lib/aws/ios/01_launch.rb +43 -0
  12. data/lib/helpers/sunomono_helpers.rb +136 -0
  13. data/lib/helpers/zip_helpers.rb +49 -0
  14. data/lib/skeleton/.gitignore +9 -0
  15. data/lib/skeleton/Gemfile +7 -0
  16. data/lib/skeleton/README.md +165 -0
  17. data/lib/skeleton/config/cucumber.yml +7 -0
  18. data/lib/skeleton/config/email/template.html +14 -0
  19. data/lib/skeleton/config/load_classes.rb +31 -0
  20. data/lib/skeleton/config/scripts/android/run_tests_all_devices.sh +41 -0
  21. data/lib/skeleton/config/scripts/android/start_emulators.sh +52 -0
  22. data/lib/skeleton/config/scripts/android/stop_emulators.sh +13 -0
  23. data/lib/skeleton/config/scripts/break_build_if_failed.sh +6 -0
  24. data/lib/skeleton/config/scripts/check_if_tests_failed.sh +11 -0
  25. data/lib/skeleton/config/scripts/ios/build_app.rb +71 -0
  26. data/lib/skeleton/config/scripts/ios/build_app.yml +13 -0
  27. data/lib/skeleton/config/scripts/ios/devices.txt +4 -0
  28. data/lib/skeleton/config/scripts/ios/run_tests_all_devices.sh +57 -0
  29. data/lib/skeleton/features/android/features/.gitkeep +0 -0
  30. data/lib/skeleton/features/android/screens/.gitkeep +0 -0
  31. data/lib/skeleton/features/android/step_definitions/.gitkeep +0 -0
  32. data/lib/skeleton/features/android/support/app_installation_hooks.rb +36 -0
  33. data/lib/skeleton/features/android/support/app_life_cycle_hooks.rb +11 -0
  34. data/lib/skeleton/features/android/support/hooks.rb +0 -0
  35. data/lib/skeleton/features/ios/features/.gitkeep +0 -0
  36. data/lib/skeleton/features/ios/screens/.gitkeep +0 -0
  37. data/lib/skeleton/features/ios/step_definitions/.gitkeep +0 -0
  38. data/lib/skeleton/features/ios/support/01_launch.rb +94 -0
  39. data/lib/skeleton/features/ios/support/02_pre_stop_hooks.rb +0 -0
  40. data/lib/skeleton/features/support/env.rb +5 -0
  41. data/lib/skeleton/features/support/exceptions.rb +11 -0
  42. data/lib/skeleton/screenshots/android/.gitkeep +0 -0
  43. data/lib/skeleton/screenshots/ios/.gitkeep +0 -0
  44. data/lib/sunomono.rb +238 -0
  45. data/lib/sunomono/locales/en.yml +27 -0
  46. data/lib/sunomono/locales/pt.yml +27 -0
  47. data/lib/sunomono/version.rb +3 -0
  48. data/lib/templates/android_screen_base.tt +186 -0
  49. data/lib/templates/base_steps.tt +48 -0
  50. data/lib/templates/feature.tt +8 -0
  51. data/lib/templates/ios_screen_base.tt +249 -0
  52. data/lib/templates/screen.tt +13 -0
  53. data/lib/templates/steps.tt +5 -0
  54. data/sunomono.gemspec +27 -0
  55. metadata +184 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f748b83e9bf8d3ac0915d62eea3116a31d22f553
4
+ data.tar.gz: d50894040a6bd70af0d64bc35b997b49ca0e8c11
5
+ SHA512:
6
+ metadata.gz: 8577fe27235665dd2ce17b5b6279fd75e2df01db093e4f00e3a349c4420ef630fa90eed3ec4ff7ee5fa5d3c7f626992653138c351e88c8b4bb6a4d0afac8bd52
7
+ data.tar.gz: 695e55f0e463ed575748ac496bc5f98a328c33a24db5a89d114efbb53b3eda53362dd5b3977d4ee0720f138bca7c786839e449440eacbf4af34ed7e888c981a4
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
15
+ .irb-history
16
+ .DS_Store
17
+ .idea/
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in sunomono.gemspec
4
+ gemspec
5
+
6
+ gem 'thor'
7
+ gem 'i18n'
8
+ gem 'json'
9
+ gem 'gherkin'
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 oscartanner
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,157 @@
1
+
2
+ ##[DEPRECATION]
3
+
4
+ This gem has been renamed to sunomono and will no longer be supported. Please switch to sunomono as soon as possible.
5
+
6
+ > See: https://rubygems.org/gems/sunomono
7
+
8
+ > And: https://github.com/concretesolutions/sunomono
9
+
10
+ # Sunomono
11
+
12
+
13
+ A simple gem to generate all files needed in a project that will support calabash for both Android and iOS.
14
+
15
+ iOS Build script works only with iOS SDK 9.2 or newer
16
+
17
+ [Calabash](http://calaba.sh/) uses cucumber to support functional tests in Android and iOS and has one gem for each Platform:
18
+
19
+ > calabash-android (for Android) [(link)](https://github.com/calabash/calabash-android)
20
+
21
+ > calabash-cucumber (for iOS) [(link)](https://github.com/calabash/calabash-ios)
22
+
23
+ The project structure is based on [this site](http://rubygemtsl.com/2014/01/06/designing-maintainable-calabash-tests-using-screen-objects-2). The structure is based on three layers: features, steps and screens.
24
+
25
+ 1. Features: Contains all the features of the project, this features are Platform independent and will run for Android and iOS tests;
26
+ 2. Steps: Contains all the steps implementations. This steps are Platform independent and will run for Android and iOS tests;
27
+ 3. Screens: Contains all the Android and iOS screens. A screen must contain an identification, the declaration of all the elements of the screen and the declaration of its actions. This layer is Platform dependent. This occurs because, in almost every project, the identification of the elements varies between the Platforms. One example is that in Android almost all elements have an id, but in iOS the most common is to identify the elements by accessibility label. The Platform dependent screens must have the same name and same methods signatures. This will allow your steps to be unique between platforms
28
+
29
+ > One example of this structure can be found in the generated files (see Usage) on the file base_steps.rb. This file implements some common steps to help you start your tests and show you how to uses the Platform dependent screens
30
+
31
+ > In my experience with tests I saw some cases that we will need to test features that are Platform dependent, like screens that send SMS which will only apper in Android apps. When this happen, the generated structure has Features and Steps that are Platform dependent and can be found inside the folder `features/android` and `features/ios` of the generated project.
32
+
33
+ ## Installation
34
+
35
+ Install it as:
36
+
37
+ $ gem install sunomono
38
+
39
+ ## Usage
40
+
41
+ In the terminal, type for help:
42
+
43
+ ```
44
+ suno
45
+ ```
46
+
47
+ Or
48
+
49
+ ```
50
+ sunomono
51
+ ```
52
+
53
+ To see the gem version type:
54
+
55
+ ```
56
+ suno version
57
+ ```
58
+
59
+ To generate a project that support both Android and iOS features type:
60
+
61
+ ```
62
+ suno new ProjectName
63
+ ```
64
+
65
+ This command will create a folder named ProjectName in the current directory and will create all the needed files. This gem support localizations. To create a localized project, in Portuguese, type:
66
+
67
+ ```
68
+ suno new ProjectName --lang=pt
69
+ ```
70
+
71
+ If you use Windows, to avoid encoding problems, run the following command in cmd:
72
+
73
+ ```
74
+ [HKEY_CURRENT_USER\Software\Microsoft\Command Processor] "AutoRun"="chcp 65001"
75
+ ```
76
+
77
+
78
+ > The default language is English ('en'). The elements of Gherkin such as Given, When, Then, And, Scenario will be translated to all Gherkin supported languages, but this gem has just a few translation files (see that in folder: `lib/sunomono/locales`).
79
+
80
+ > **Sunomono doesn't support your mother language?** No problem. Fork it, create your yml translation file, uses the en.yml file as a template. Translate it and make a pull request. There are only 15 lines to be translated, this will take no time.
81
+
82
+ > **Want to know how to name your translation yml file?** See the Gherkin supported languages [here](https://github.com/cucumber/gherkin/blob/master/lib/gherkin/i18n.json) for reference.
83
+
84
+ Once the project is created, open its folder (`cd ProjectName`) and run `bundle install`
85
+
86
+ > Remember to fix the calabash-cucumber version on the Gemfile. When updating the calabash-cucumber gem version you need to update the Calabash framework that was embedded on your iOS code. So, my suggestion is to update it manually. [In this page](https://github.com/calabash/calabash-ios/wiki/B1-Updating-your-Calabash-iOS-version) you can find more information on how to update the Calabash framework.
87
+
88
+
89
+ There are nine generators that are responsible to create the templates for Features, Step definitions and Screens.
90
+
91
+ **The generators commands ONLY WORK in the ROOT FOLDER of the project**.
92
+
93
+ ####Features
94
+
95
+ ```
96
+ suno generate feature FeatureName
97
+ ```
98
+ The feature generator will create a Platform independent feature and its files. So this command will create the FeatureName.feature file inside the folder `feature`, the file FeatureName_steps.rb inside the folder `features/step_definitions`, the files FeatureName_screen.rb inside the folders `features/android/screens` and `features/ios/screens`.
99
+
100
+
101
+ ```
102
+ suno generate android-feature AndroidFeatureName
103
+ suno generate ios-feature iOSFeatureName
104
+ ```
105
+ The aFeature and iFeature generator will create an Platform dependent feature. For example, the aFeature generator will create the AndroidFeatureName.feature file inside the folder `features/android/features`, the file AndroidFeatureName_steps.rb inside the folder `features/androd/step_definitions` and the screen file AndroidFeatureName_screen.rb inside the folder `features/android/screens`.
106
+
107
+
108
+ Don't forget about internationalization. All the generators accept the option `--lang=pt` or with some other language.
109
+
110
+ ####Steps
111
+
112
+ ```
113
+ suno generate step StepName
114
+ ```
115
+ The step generator will create a Platform independent step file named StepName_steps.rb in the folder `features/step_definitions`
116
+
117
+
118
+ ```
119
+ suno generate android-step AndroidStepName
120
+ ```
121
+ The android-step generator will create an Android step file named AndroidStepName_steps.rb in the folder `features/android/step_definitions`
122
+
123
+
124
+ ```
125
+ suno generate ios-step iOSStepName
126
+ ```
127
+ The iStep generator will create an iOS step file name iOSStepName_steps.rb in the folder `features/ios/step_definitions`
128
+
129
+
130
+
131
+ ####Screens
132
+
133
+ ```
134
+ suno generate screen ScreenName
135
+ ```
136
+ The screen generator will create both Platform dependent screens in the folders `features/android/screens` and `features/ios/screens`.
137
+
138
+
139
+ ```
140
+ suno generate android-screen AndroidScreenName
141
+ suno generate ios-screen iOSScreenName
142
+ ```
143
+ The android-screen and ios-screen will create only the Android and iOS dependent screens respectively.
144
+
145
+ ## Continuous Integration (CI)
146
+
147
+ The project contains a lot of scripts that will help you to configure you CI server.
148
+
149
+ > Documentation under development.
150
+
151
+ ## Contributing
152
+
153
+ 1. Fork it ( https://github.com/concretesolutions/cs-bdd/fork )
154
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
155
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
156
+ 4. Push to the branch (`git push origin my-new-feature`)
157
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require 'bundler/gem_tasks'
data/bin/suno ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ require 'sunomono'
3
+ Sunomono::SunomonoRunner.start
data/bin/sunomono ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ require 'sunomono'
3
+ Sunomono::SunomonoRunner.start
@@ -0,0 +1,30 @@
1
+ require 'calabash-android/management/app_installation'
2
+
3
+ AfterConfiguration do |config|
4
+ FeatureMemory.feature = nil
5
+ end
6
+
7
+ Before do |scenario|
8
+ @scenario_is_outline = (scenario.class ==
9
+ Cucumber::Ast::OutlineTable::ExampleRow)
10
+ scenario = scenario.scenario_outline if @scenario_is_outlinel
11
+
12
+ feature = scenario.feature
13
+ if FeatureMemory.feature != feature || ENV['RESET_BETWEEN_SCENARIOS'] == '1'
14
+ if ENV['RESET_BETWEEN_SCENARIOS'] == '1'
15
+ log 'New scenario - reinstalling apps'
16
+ else
17
+ log 'First scenario in feature - reinstalling apps'
18
+ end
19
+
20
+ uninstall_apps
21
+ install_app(ENV['TEST_APP_PATH'])
22
+ install_app(ENV['APP_PATH'])
23
+ FeatureMemory.feature = feature
24
+ FeatureMemory.invocation = 1
25
+ else
26
+ FeatureMemory.invocation += 1
27
+ end
28
+ end
29
+
30
+ FeatureMemory = Struct.new(:feature, :invocation).new
@@ -0,0 +1,13 @@
1
+ require 'calabash-android/management/adb'
2
+ require 'calabash-android/operations'
3
+
4
+ Before do |scenario|
5
+ start_test_server_in_background
6
+ end
7
+
8
+ After do |scenario|
9
+ if scenario.failed?
10
+ screenshot_embed
11
+ end
12
+ shutdown_test_server
13
+ end
@@ -0,0 +1,43 @@
1
+ require 'calabash-cucumber/launcher'
2
+
3
+ # You can find examples of more complicated launch hooks in these
4
+ # two repositories:
5
+ #
6
+ # https://github.com/calabash/ios-smoke-test-app/blob/master/CalSmokeApp/features/support/01_launch.rb
7
+ # https://github.com/calabash/ios-webview-test-app/blob/master/CalWebViewApp/features/support/01_launch.rb
8
+
9
+ module Calabash::Launcher
10
+ @@launcher = nil
11
+
12
+ def self.launcher
13
+ @@launcher ||= Calabash::Cucumber::Launcher.new
14
+ end
15
+
16
+ def self.launcher=(launcher)
17
+ @@launcher = launcher
18
+ end
19
+ end
20
+
21
+ Before do
22
+ launcher = Calabash::Launcher.launcher
23
+ options = {
24
+ timeout: 3000
25
+ }
26
+
27
+ launcher.relaunch(options)
28
+ end
29
+
30
+ After do |scenario|
31
+ # Calabash can shutdown the app cleanly by calling the app life cycle methods
32
+ # in the UIApplicationDelegate. This is really nice for CI environments, but
33
+ # not so good for local development.
34
+ #
35
+ # See the documentation for QUIT_APP_AFTER_SCENARIO for a nice debugging workflow
36
+ #
37
+ # http://calabashapi.xamarin.com/ios/file.ENVIRONMENT_VARIABLES.html#label-QUIT_APP_AFTER_SCENARIO
38
+ # http://calabashapi.xamarin.com/ios/Calabash/Cucumber/Core.html#console_attach-instance_method
39
+ if launcher.quit_app_after_scenario?
40
+ calabash_exit
41
+ end
42
+ end
43
+
@@ -0,0 +1,136 @@
1
+ # -*- coding: utf-8 -*-
2
+ require_relative 'zip_helpers'
3
+
4
+ def create_feature_file(name, platform = nil)
5
+ # options used to generate the file in the template function
6
+ opts = { name: camelize(name) }
7
+
8
+ # If platform is not nil than the feature is OS dependent
9
+ file_path = ''
10
+ if platform.nil?
11
+ file_path = File.join(FileUtils.pwd, 'features', "#{name.downcase}.feature")
12
+ opts[:platform] = ''
13
+ else
14
+ file_path = File.join(
15
+ FileUtils.pwd, 'features', platform.downcase, 'features',
16
+ "#{name.downcase}.feature"
17
+ )
18
+ opts[:platform] = platform
19
+ end
20
+
21
+ # Thor creates a file based on the templates/feature.tt template
22
+ template('feature', file_path, opts)
23
+ end
24
+
25
+ def create_steps_file(name, platform = nil)
26
+ # options used to generate the file in the template function
27
+ opts = { name: camelize(name) }
28
+
29
+ # If platform is not nil than the step is OS dependent
30
+ file_path = nil
31
+ if platform.nil?
32
+ file_path = File.join(
33
+ FileUtils.pwd, 'features', 'step_definitions',
34
+ "#{name.downcase}_steps.rb"
35
+ )
36
+ opts[:platform] = ''
37
+ else
38
+ file_path = File.join(
39
+ FileUtils.pwd, 'features', platform.downcase, 'step_definitions',
40
+ "#{name.downcase}_steps.rb"
41
+ )
42
+ opts[:platform] = platform
43
+ end
44
+
45
+ # Thor creates a file based on the templates/steps.tt template
46
+ template('steps', file_path, opts)
47
+ end
48
+
49
+ def create_screen_file(name, platform)
50
+ # options used to generate the file in the template function
51
+ opts = { name: camelize(name), platform: platform }
52
+
53
+ # Thor creates a file based on the templates/screen.tt template
54
+ template('screen',
55
+ File.join(
56
+ FileUtils.pwd, 'features', platform.downcase, 'screens',
57
+ "#{name.downcase}_screen.rb"
58
+ ), opts)
59
+ end
60
+
61
+ def camelize(string)
62
+ camelized = ''
63
+
64
+ string.split('_').each do |s|
65
+ camelized += s.capitalize
66
+ end
67
+
68
+ camelized
69
+ end
70
+
71
+ def in_root_project_folder?
72
+ # Looks if the user is in the root folder of the project
73
+ if !Dir.exist?(File.join(FileUtils.pwd, 'features', 'android', 'features')) ||
74
+ !Dir.exist?(File.join(FileUtils.pwd, 'features', 'ios', 'features'))
75
+ puts 'Please run this command on the root folder of the project'
76
+ exit 1
77
+ end
78
+
79
+ true
80
+ end
81
+
82
+ def create_zip_folder(dir)
83
+ file_name = "#{Time.now.strftime('%Y%m%d%H%M%S')}_specs.zip"
84
+ zf = ZipFileGenerator.new(dir, file_name)
85
+ zf.write
86
+ say_status(:create, file_name)
87
+ end
88
+
89
+ # Looks for special chars in the specs folder
90
+ def special_chars_in_exported_path?
91
+ entries = `grep -inrE 'á|â|ã|é|ê|í|ó|õ|ô|ú|ç' . --exclude-dir={.git,screenshots,config,support,test_servers} --exclude='*.zip'`
92
+ if entries.count("\n") > 0
93
+ puts_special_chars_error_message(entries)
94
+ exit 1
95
+ end
96
+ end
97
+
98
+ def puts_special_chars_error_message(entries)
99
+ puts <<-EOF
100
+ There are special chars in your specs.
101
+ This can block AWS Device Farm execution.'
102
+ Entries found:
103
+ #{entries}
104
+
105
+ To skip this validation use: '--skip-char-validation'
106
+ Exiting..."
107
+ EOF
108
+ end
109
+
110
+ # Copies all folders and files from specs that are valid in AWS context
111
+ def copy_all_project_files(dir)
112
+ directory FileUtils.pwd, dir,
113
+ exclude_pattern: /(.git|.DS_Store|.irb-history|.gitignore|.gitkeep|screenshot|.apk|.zip)/
114
+ # Replacing launcher files to avoid problems with AWS Device Farm
115
+ copy_file File.join(File.dirname(__FILE__), '..', 'aws',
116
+ 'android', 'app_installation_hooks.rb'),
117
+ File.join(dir, 'features', 'android',
118
+ 'support', 'app_installation_hooks.rb'),
119
+ force: true
120
+ copy_file File.join(File.dirname(__FILE__), '..', 'aws',
121
+ 'android', 'app_life_cycle_hooks.rb'),
122
+ File.join(dir, 'features', 'android',
123
+ 'support', 'app_life_cycle_hooks.rb'),
124
+ force: true
125
+ copy_file File.join(File.dirname(__FILE__), '..', 'aws',
126
+ 'ios', '01_launch.rb'),
127
+ File.join(dir, 'features', 'ios',
128
+ 'support', '01_launch.rb'),
129
+ force: true
130
+ end
131
+
132
+ def create_screen_shot_dirs(dir)
133
+ Dir.mkdir File.join(dir, 'screenshots')
134
+ Dir.mkdir File.join(dir, 'screenshots', 'ios')
135
+ Dir.mkdir File.join(dir, 'screenshots', 'android')
136
+ end