calabash 1.2.1 → 1.9.9.pre1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (137) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +39 -0
  3. data/LICENSE +204 -21
  4. data/README.md +36 -6
  5. data/VERSIONING.md +16 -0
  6. data/bin/calabash +95 -0
  7. data/lib/calabash.rb +185 -1
  8. data/lib/calabash/android.rb +64 -0
  9. data/lib/calabash/android/adb.rb +277 -0
  10. data/lib/calabash/android/application.rb +110 -0
  11. data/lib/calabash/android/build.rb +12 -0
  12. data/lib/calabash/android/build/application.rb +13 -0
  13. data/lib/calabash/android/build/build_error.rb +11 -0
  14. data/lib/calabash/android/build/builder.rb +119 -0
  15. data/lib/calabash/android/build/java_keystore.rb +177 -0
  16. data/lib/calabash/android/build/resigner.rb +56 -0
  17. data/lib/calabash/android/build/test_server.rb +27 -0
  18. data/lib/calabash/android/console_helpers.rb +44 -0
  19. data/lib/calabash/android/cucumber.rb +3 -0
  20. data/lib/calabash/android/device.rb +965 -0
  21. data/lib/calabash/android/environment.rb +470 -0
  22. data/lib/calabash/android/gestures.rb +369 -0
  23. data/lib/calabash/android/interactions.rb +45 -0
  24. data/lib/calabash/android/lib/.irbrc +55 -0
  25. data/lib/calabash/android/lib/AndroidManifest.xml +51 -0
  26. data/lib/calabash/android/lib/TestServer.apk +0 -0
  27. data/lib/calabash/android/lib/calmd5/arm64-v8a/calmd5 +0 -0
  28. data/lib/calabash/android/lib/calmd5/arm64-v8a/calmd5-pie +0 -0
  29. data/lib/calabash/android/lib/calmd5/armeabi-v7a/calmd5 +0 -0
  30. data/lib/calabash/android/lib/calmd5/armeabi-v7a/calmd5-pie +0 -0
  31. data/lib/calabash/android/lib/calmd5/armeabi/calmd5 +0 -0
  32. data/lib/calabash/android/lib/calmd5/armeabi/calmd5-pie +0 -0
  33. data/lib/calabash/android/lib/calmd5/mips/calmd5 +0 -0
  34. data/lib/calabash/android/lib/calmd5/mips/calmd5-pie +0 -0
  35. data/lib/calabash/android/lib/calmd5/mips64/calmd5 +0 -0
  36. data/lib/calabash/android/lib/calmd5/mips64/calmd5-pie +0 -0
  37. data/lib/calabash/android/lib/calmd5/x86/calmd5 +0 -0
  38. data/lib/calabash/android/lib/calmd5/x86/calmd5-pie +0 -0
  39. data/lib/calabash/android/lib/calmd5/x86_64/calmd5 +0 -0
  40. data/lib/calabash/android/lib/calmd5/x86_64/calmd5-pie +0 -0
  41. data/lib/calabash/android/lib/screenshot_taker.jar +0 -0
  42. data/lib/calabash/android/life_cycle.rb +37 -0
  43. data/lib/calabash/android/orientation.rb +30 -0
  44. data/lib/calabash/android/physical_buttons.rb +39 -0
  45. data/lib/calabash/android/screenshot.rb +9 -0
  46. data/lib/calabash/android/scroll.rb +5 -0
  47. data/lib/calabash/android/server.rb +10 -0
  48. data/lib/calabash/android/text.rb +54 -0
  49. data/lib/calabash/application.rb +74 -0
  50. data/lib/calabash/cli.rb +12 -0
  51. data/lib/calabash/cli/build.rb +33 -0
  52. data/lib/calabash/cli/console.rb +90 -0
  53. data/lib/calabash/cli/generate.rb +110 -0
  54. data/lib/calabash/cli/helpers.rb +130 -0
  55. data/lib/calabash/cli/resign.rb +33 -0
  56. data/lib/calabash/cli/run.rb +99 -0
  57. data/lib/calabash/cli/setup_keystore.rb +39 -0
  58. data/lib/calabash/color.rb +32 -0
  59. data/lib/calabash/console_helpers.rb +90 -0
  60. data/lib/calabash/defaults.rb +56 -0
  61. data/lib/calabash/device.rb +401 -0
  62. data/lib/calabash/environment.rb +75 -0
  63. data/lib/calabash/gestures.rb +384 -0
  64. data/lib/calabash/http.rb +8 -0
  65. data/lib/calabash/http/error.rb +15 -0
  66. data/lib/calabash/http/request.rb +42 -0
  67. data/lib/calabash/http/retriable_client.rb +156 -0
  68. data/lib/calabash/interactions.rb +105 -0
  69. data/lib/calabash/ios.rb +37 -0
  70. data/lib/calabash/ios/application.rb +119 -0
  71. data/lib/calabash/ios/conditions.rb +79 -0
  72. data/lib/calabash/ios/console_helpers.rb +72 -0
  73. data/lib/calabash/ios/device.rb +24 -0
  74. data/lib/calabash/ios/device/device_implementation.rb +779 -0
  75. data/lib/calabash/ios/device/gestures_mixin.rb +167 -0
  76. data/lib/calabash/ios/device/keyboard_mixin.rb +133 -0
  77. data/lib/calabash/ios/device/physical_device_mixin.rb +266 -0
  78. data/lib/calabash/ios/device/rotation_mixin.rb +124 -0
  79. data/lib/calabash/ios/device/routes/backdoor_route_mixin.rb +86 -0
  80. data/lib/calabash/ios/device/routes/condition_route_mixin.rb +62 -0
  81. data/lib/calabash/ios/device/routes/error.rb +8 -0
  82. data/lib/calabash/ios/device/routes/handle_route_mixin.rb +102 -0
  83. data/lib/calabash/ios/device/routes/map_route_mixin.rb +38 -0
  84. data/lib/calabash/ios/device/routes/playback_route_mixin.rb +70 -0
  85. data/lib/calabash/ios/device/routes/response_parser.rb +48 -0
  86. data/lib/calabash/ios/device/routes/uia_route_mixin.rb +238 -0
  87. data/lib/calabash/ios/device/runtime_attributes.rb +184 -0
  88. data/lib/calabash/ios/device/status_bar_mixin.rb +17 -0
  89. data/lib/calabash/ios/device/text_mixin.rb +19 -0
  90. data/lib/calabash/ios/device/uia_keyboard_mixin.rb +188 -0
  91. data/lib/calabash/ios/device/uia_mixin.rb +12 -0
  92. data/lib/calabash/ios/environment.rb +41 -0
  93. data/lib/calabash/ios/interactions.rb +10 -0
  94. data/lib/calabash/ios/lib/.irbrc +55 -0
  95. data/lib/calabash/ios/lib/recordings/rotate_left_home_down_ipad.base64 +2 -0
  96. data/lib/calabash/ios/lib/recordings/rotate_left_home_down_iphone.base64 +2 -0
  97. data/lib/calabash/ios/lib/recordings/rotate_left_home_left_ipad.base64 +2 -0
  98. data/lib/calabash/ios/lib/recordings/rotate_left_home_left_iphone.base64 +2 -0
  99. data/lib/calabash/ios/lib/recordings/rotate_left_home_right_ipad.base64 +2 -0
  100. data/lib/calabash/ios/lib/recordings/rotate_left_home_right_iphone.base64 +2 -0
  101. data/lib/calabash/ios/lib/recordings/rotate_left_home_up_ipad.base64 +2 -0
  102. data/lib/calabash/ios/lib/recordings/rotate_left_home_up_iphone.base64 +2 -0
  103. data/lib/calabash/ios/lib/recordings/rotate_right_home_down_ipad.base64 +2 -0
  104. data/lib/calabash/ios/lib/recordings/rotate_right_home_down_iphone.base64 +2 -0
  105. data/lib/calabash/ios/lib/recordings/rotate_right_home_left_ipad.base64 +2 -0
  106. data/lib/calabash/ios/lib/recordings/rotate_right_home_left_iphone.base64 +2 -0
  107. data/lib/calabash/ios/lib/recordings/rotate_right_home_right_ipad.base64 +2 -0
  108. data/lib/calabash/ios/lib/recordings/rotate_right_home_right_iphone.base64 +2 -0
  109. data/lib/calabash/ios/lib/recordings/rotate_right_home_up_ipad.base64 +2 -0
  110. data/lib/calabash/ios/lib/recordings/rotate_right_home_up_iphone.base64 +2 -0
  111. data/lib/calabash/ios/orientation.rb +117 -0
  112. data/lib/calabash/ios/scroll.rb +504 -0
  113. data/lib/calabash/ios/server.rb +73 -0
  114. data/lib/calabash/ios/text.rb +248 -0
  115. data/lib/calabash/ios/uia.rb +24 -0
  116. data/lib/calabash/lib/skeleton/config/cucumber.yml +6 -0
  117. data/lib/calabash/lib/skeleton/features/sample.feature +5 -0
  118. data/lib/calabash/lib/skeleton/features/step_definitions/calabash_steps.rb +29 -0
  119. data/lib/calabash/lib/skeleton/features/support/env.rb +54 -0
  120. data/lib/calabash/lib/skeleton/features/support/hooks.rb +83 -0
  121. data/lib/calabash/life_cycle.rb +111 -0
  122. data/lib/calabash/location.rb +51 -0
  123. data/lib/calabash/logger.rb +87 -0
  124. data/lib/calabash/orientation.rb +84 -0
  125. data/lib/calabash/page.rb +35 -0
  126. data/lib/calabash/patch.rb +14 -0
  127. data/lib/calabash/patch/array.rb +16 -0
  128. data/lib/calabash/patch/run_loop.rb +90 -0
  129. data/lib/calabash/query.rb +160 -0
  130. data/lib/calabash/query_result.rb +85 -0
  131. data/lib/calabash/screenshot.rb +89 -0
  132. data/lib/calabash/server.rb +16 -0
  133. data/lib/calabash/text.rb +76 -0
  134. data/lib/calabash/utility.rb +58 -0
  135. data/lib/calabash/version.rb +3 -1
  136. data/lib/calabash/wait.rb +474 -0
  137. metadata +462 -24
@@ -0,0 +1,110 @@
1
+ require 'fileutils'
2
+
3
+ module Calabash
4
+ # @!visibility private
5
+ module CLI
6
+ # @!visibility private
7
+ module Generate
8
+ def parse_generate_arguments!
9
+ type = @arguments.shift
10
+
11
+ if type.nil?
12
+ msg("Question") do
13
+ puts "Calabash is about to create a subdirectory called features and config,"
14
+ puts "features will contain all your calabash tests."
15
+ puts "Please hit return to confirm that's what you want."
16
+ end
17
+
18
+ unless STDIN.gets.chomp == ''
19
+ exit 2
20
+ end
21
+
22
+ if File.exist?('features')
23
+ puts "A features directory already exists. Please remove this to continue."
24
+ exit 1
25
+ end
26
+
27
+ if File.exist?('config')
28
+ puts "A config directory already exists. Please remove this to continue."
29
+ exit 1
30
+ end
31
+
32
+ reset_between = nil
33
+ reset_method = nil
34
+
35
+ puts "Do you want to reset the app by default? ((n)ever/between (s)cenarios/between (f)eatures) "
36
+ input = STDIN.gets.chomp.downcase
37
+
38
+ case input
39
+ when 'n'
40
+ reset_between = :never
41
+ when 's'
42
+ reset_between = :scenarios
43
+ when 'f'
44
+ reset_between = :features
45
+ else
46
+ puts "Invalid input '#{input}'"
47
+ exit(3)
48
+ end
49
+
50
+ unless reset_between == :never
51
+ puts "How would you like to reset the app by default? ((c)learing/(r)einstalling) "
52
+ input = STDIN.gets.chomp.downcase
53
+
54
+ case input
55
+ when 'c'
56
+ reset_method = :clear
57
+ when 'r'
58
+ reset_method = :reinstall
59
+ else
60
+ puts "Invalid input '#{input}'"
61
+ exit(4)
62
+ end
63
+ end
64
+
65
+ cucumber_config = File.read(file(File.join('config', 'cucumber.yml')))
66
+
67
+ env = File.read(file(File.join('features', 'support', 'env.rb')))
68
+ sample_feature = File.read(file(File.join('features', 'sample.feature')))
69
+ calabash_steps = File.read(file(File.join('features', 'step_definitions', 'calabash_steps.rb')))
70
+
71
+ hooks = File.read(file(File.join('features', 'support', 'hooks.rb')))
72
+ hooks.sub!("#!DEFAULT_RESET_BETWEEN#!", ":#{reset_between}")
73
+
74
+ if reset_method.nil?
75
+ hooks.sub!("#!DEFAULT_RESET_METHOD#!", 'nil')
76
+ else
77
+ hooks.sub!("#!DEFAULT_RESET_METHOD#!", ":#{reset_method}")
78
+ end
79
+
80
+ FileUtils.mkdir('config')
81
+
82
+ File.open(File.join('config', 'cucumber.yml'), 'w') {|file| file.write(cucumber_config) }
83
+
84
+ FileUtils.mkdir('features')
85
+ FileUtils.mkdir('features/step_definitions')
86
+ FileUtils.mkdir('features/support')
87
+
88
+ File.open(File.join('features', 'sample.feature'), 'w') {|file| file.write(sample_feature) }
89
+ File.open(File.join('features', 'step_definitions', 'calabash_steps.rb'), 'w') {|file| file.write(calabash_steps) }
90
+ File.open(File.join('features', 'support', 'hooks.rb'), 'w') {|file| file.write(hooks) }
91
+ File.open(File.join('features', 'support', 'env.rb'), 'w') {|file| file.write(env) }
92
+ else
93
+ fail("Invalid argument #{type}", :gen)
94
+ end
95
+ end
96
+
97
+ def file(file)
98
+ File.join(Calabash::Environment::SKELETON_DIR_PATH, file)
99
+ end
100
+
101
+ def msg(title, &block)
102
+ puts "\n" + "-"*10 + title + "-"*10
103
+ block.call
104
+ puts "-"*10 + "-------" + "-"*10 + "\n"
105
+ end
106
+
107
+
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,130 @@
1
+ module Calabash
2
+ # @!visibility private
3
+ module CLI
4
+ # @!visibility private
5
+ module Helpers
6
+ HELP = {
7
+ help: 'help',
8
+ gen: 'gen',
9
+ run: 'run [application] [cucumber options]',
10
+ console: 'console [application]',
11
+ version: 'version',
12
+ setup_keystore: 'setup-keystore',
13
+ resign: 'resign <apk>',
14
+ build: 'build <apk>'
15
+ }
16
+
17
+ def key_for_command(command)
18
+ HELP.each do |key, value|
19
+ if value.split(' ').first == command
20
+ return key
21
+ end
22
+ end
23
+
24
+ nil
25
+ end
26
+
27
+ def print_usage_for(key, output=STDOUT)
28
+ if key.nil? || HELP[key].nil?
29
+ output.write <<EOF
30
+ No such command '#{command}'
31
+ EOF
32
+ else
33
+ output.write <<EOF
34
+ Usage:
35
+ calabash [options] #{HELP[key]}
36
+ EOF
37
+ end
38
+ end
39
+
40
+ def print_usage(output=STDOUT)
41
+ output.write <<EOF
42
+ Usage: calabash [options] <command-name> [command specific options]
43
+ <command-name> can be one of
44
+ #{HELP[:help]} [command]
45
+ print help information.
46
+
47
+ #{HELP[:gen]}
48
+ generate a features folder structure.
49
+
50
+ #{HELP[:run]}
51
+ runs Cucumber in the current folder with the environment needed.
52
+ the cucumber options will be passed unchanged to cucumber
53
+
54
+ #{HELP[:console]}
55
+ starts an interactive console to interact with your app via Calabash
56
+
57
+ #{HELP[:version]}
58
+ prints the gem version
59
+
60
+ Android specific commands
61
+ #{HELP[:setup_keystore]}
62
+ sets up a non-default keystore to use with this test project.
63
+
64
+ #{HELP[:resign]}
65
+ resigns the app with the currently configured keystore.
66
+
67
+ #{HELP[:build]}
68
+ builds the test server that will be used when testing the app.
69
+
70
+ iOS specific commands
71
+ setup <path>
72
+ setup your XCode project for calabash-ios (EXPERIMENTAL)
73
+
74
+ check <{path to .ipa|<path to .app}>
75
+ check whether an app or ipa is linked with calabash.framework (EXPERIMENTAL)
76
+
77
+ download
78
+ install latest compatible version of calabash.framework
79
+
80
+ check <{path to .ipa|path to .app}>
81
+ check whether an app or ipa is linked with calabash.framework
82
+
83
+ sim locale <lang> [region]
84
+ change locale and regional settings in all iOS Simulators
85
+
86
+ sim location <{on|off}> [path to .app]
87
+ set allow location on/off for current project or app
88
+
89
+ sim reset
90
+ reset content and settings in all iOS Simulators
91
+
92
+ sim acc
93
+ enable accessibility in all iOS Simulators
94
+
95
+ sim device {iPad|iPad_Retina|iPhone|iPhone_Retina|iPhone_Retina_4inch}
96
+ change the default iOS Simulator device.
97
+
98
+ [options] can be
99
+ -v, --verbose
100
+ Turns on verbose logging
101
+ EOF
102
+ end
103
+
104
+ def help
105
+ file_name = File.join(File.dirname(__FILE__), '..', 'doc', 'calabash_help.txt')
106
+ system("less \"#{file_name}\"")
107
+ end
108
+
109
+ def fail(reason, command=nil)
110
+ STDERR.write("#{reason}\n")
111
+
112
+ if command != nil
113
+ print_usage_for(command)
114
+ end
115
+
116
+ exit(1)
117
+ end
118
+ end
119
+ end
120
+ end
121
+
122
+ # Removed commands
123
+ =begin
124
+ iOS:
125
+ update [target]
126
+ updates one of the following targets: hooks
127
+
128
+
129
+
130
+ =end
@@ -0,0 +1,33 @@
1
+ module Calabash
2
+ # @!visibility private
3
+ module CLI
4
+ # @!visibility private
5
+ module Resign
6
+ def parse_resign_arguments!
7
+ fail('Can only resign Android applications') unless @platform.nil? || @platform == :android
8
+
9
+ application = @arguments.shift
10
+
11
+ if application.nil?
12
+ fail('Must supply application as first parameter to resign', :resign)
13
+ elsif !File.exists?(application)
14
+ fail("File '#{application}' does not exist", :resign)
15
+ else
16
+ extension = File.extname(application)
17
+
18
+ case extension
19
+ when '.apk'
20
+ set_platform!(:android)
21
+ Calabash::Android::Build::Resigner.new(application).resign!
22
+ when '.ipa', '.app'
23
+ set_platform!(:ios)
24
+ fail('Can only resign Android applications (apk)')
25
+ else
26
+ fail('Application must be an apk', :resign)
27
+ end
28
+ end
29
+ end
30
+
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,99 @@
1
+ module Calabash
2
+ # @!visibility private
3
+ module CLI
4
+ # @!visibility private
5
+ module Run
6
+ def parse_run_arguments!
7
+ first_argument = @arguments.first # Do not remove the entry from the arguments yet - it might be a cucumber arg
8
+
9
+ if first_argument.nil? || first_argument.start_with?('-') || first_argument =~ /\.feature(\:\d*|\z)/
10
+ # If the argument begins with a dash, we assume the user meant
11
+ # to specify a cucumber argument, not an application
12
+ # If the argument ends with .feature, we assume the user meant
13
+ # to specify a cucumber argument, not an application.
14
+ Logger.info("No application specified. Using default application specified by env variable CAL_APP")
15
+ application = Environment::APP_PATH
16
+ Logger.debug("New application: '#{application}'")
17
+
18
+ fail("No application given and env variable CAL_APP is not set.", :run) if application.nil?
19
+ else
20
+ # If the argument does not begin with a dash, we assume the user meant
21
+ # to specify an application, not a cucumber argument
22
+ application = @arguments.shift
23
+ end
24
+
25
+ if File.exists?(application)
26
+ extension = File.extname(application)
27
+ application_path = File.expand_path(application)
28
+
29
+ case extension
30
+ when '.apk'
31
+ set_platform!(:android)
32
+
33
+ # Create the test server if it does not exist
34
+ test_server = Android::Build::TestServer.new(application_path)
35
+
36
+ unless test_server.exists?
37
+ Logger.info('Test server does not exist. Creating test server.')
38
+ Calabash::Android::Build::Builder.new(application_path).build
39
+ end
40
+
41
+ run(application_path, @arguments)
42
+ when '.ipa'
43
+ set_platform!(:ios)
44
+ # TODO: Extract ID from ipa
45
+ raise 'FOR NOW WE CANT DO THIS'
46
+ when '.app'
47
+ set_platform!(:ios)
48
+ run(application_path, @arguments)
49
+ else
50
+ fail('Application must be either an .apk, .ipa or .app', :run)
51
+ end
52
+ else
53
+ fail("File '#{application}' does not exist", :run)
54
+ end
55
+ end
56
+
57
+ def run(application_path, cucumber_arguments)
58
+ cucumber_environment = {}
59
+ cucumber_environment['CAL_DEBUG'] = Environment::DEBUG ? '1' : '0'
60
+
61
+ if @options[:verbose]
62
+ cucumber_environment['CAL_DEBUG'] = '1'
63
+ end
64
+
65
+ if @platform == :android
66
+ cucumber_environment['CAL_APP'] = application_path
67
+
68
+ if Environment::TEST_SERVER_PATH
69
+ cucumber_environment['CAL_TEST_SERVER'] = Environment::TEST_SERVER_PATH
70
+ else
71
+ test_server = Android::Build::TestServer.new(application_path)
72
+
73
+ raise 'Cannot locate test-server' unless test_server.exists?
74
+
75
+ cucumber_environment['CAL_TEST_SERVER'] = test_server.path
76
+ end
77
+ elsif @platform == :ios
78
+ cucumber_environment['CAL_APP'] = application_path
79
+ else
80
+ raise "Invalid platform '#{@platform}'"
81
+ end
82
+
83
+ begin
84
+ require 'cucumber'
85
+ rescue LoadError => _
86
+ unless Object.const_defined?(:Bundler)
87
+ $stderr.puts "Warning! Could not load cucumber. Make sure it is installed."
88
+ end
89
+ end
90
+
91
+ arguments = ['-S', 'cucumber', '-p', @platform.to_s, *cucumber_arguments]
92
+
93
+ Logger.debug("Starting Ruby with arguments: #{arguments.join(', ')} and environment #{cucumber_environment.to_s}")
94
+
95
+ exec(cucumber_environment, RbConfig.ruby, *arguments)
96
+ end
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,39 @@
1
+ require 'json'
2
+ require 'awesome_print'
3
+ require 'io/console'
4
+
5
+ module Calabash
6
+ module CLI
7
+ # @!visibility private
8
+ module SetupKeystore
9
+ def parse_setup_keystore_arguments!
10
+ set_platform!(:android)
11
+
12
+ settings = {}
13
+
14
+ puts "Please enter keystore information to use a custom keystore instead of the default"
15
+
16
+ settings[:keystore_location] = File.expand_path(prompt('Please enter a path to the keystore'))
17
+ settings[:keystore_store_password] = prompt('Please enter the password for the keystore (storepass)', true)
18
+ settings[:keystore_alias] = prompt('Please enter the alias. Leave blank for auto-detection.')
19
+ settings[:keystore_key_password] = prompt('Please enter the password for the key (keypass). Leave blank if it is the same as the store password.', true)
20
+
21
+ File.open(Android::Build::JavaKeystore::CALABASH_KEYSTORE_SETTINGS_FILENAME, 'w') do |file|
22
+ file.puts(JSON.pretty_generate(settings))
23
+ end
24
+
25
+ puts "Saved your settings to '#{Android::Build::JavaKeystore::CALABASH_KEYSTORE_SETTINGS_FILENAME}'. You can edit the settings manually or run this setup script again"
26
+ end
27
+
28
+ def prompt(message, secure = false)
29
+ puts message
30
+
31
+ if secure
32
+ STDIN.noecho(&:gets).chomp
33
+ else
34
+ STDIN.gets.chomp
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,32 @@
1
+ module Calabash
2
+ # @!visibility private
3
+ module Color
4
+ def self.colorize(string, color)
5
+ "\e[#{color}m#{string}\e[0m"
6
+ end
7
+
8
+ def self.red(string)
9
+ colorize(string, 31)
10
+ end
11
+
12
+ def self.green(string)
13
+ colorize(string, 32)
14
+ end
15
+
16
+ def self.yellow(string)
17
+ colorize(string, 33)
18
+ end
19
+
20
+ def self.blue(string)
21
+ colorize(string, 34)
22
+ end
23
+
24
+ def self.magenta(string)
25
+ colorize(string, 35)
26
+ end
27
+
28
+ def self.cyan(string)
29
+ colorize(string, 36)
30
+ end
31
+ end
32
+ end