testingbot 0.0.9 → 0.1.0

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.
@@ -1,30 +1,35 @@
1
1
  require 'testingbot/config'
2
+ require 'testingbot/capybara'
3
+ require 'testingbot/api'
2
4
 
3
5
  if defined?(Cucumber)
4
- After do |scenario|
5
- client_key = TestingBot.get_config[:client_key]
6
- client_secret = TestingBot.get_config[:client_secret]
7
-
8
- if Capybara.drivers.include?(:testingbot) && !TestingBot.get_config[:client_key].nil?
9
- begin
10
- session_id = page.driver.browser.instance_variable_get("@bridge").instance_variable_get("@session_id")
11
-
12
- params = {
13
- "session_id" => session_id,
14
- "client_key" => client_key,
15
- "client_secret" => client_secret,
16
- "status_message" => (scenario.failed? ? scenario.exception.message : ""),
17
- "success" => !scenario.failed?,
18
- "name" => scenario.title,
19
- "kind" => 2
20
- }
21
-
22
- url = URI.parse('http://testingbot.com/hq')
23
- http = Net::HTTP.new(url.host, url.port)
24
- response = http.post(url.path, params.map { |k, v| "#{k.to_s}=#{v}" }.join("&"))
25
- rescue Exception => e
26
- p "Could not determine sessionID, can not send results to TestingBot.com #{e.message}"
27
- end
28
- end
29
- end
6
+ Before('@selenium') do
7
+ ::Capybara.current_driver = :testingbot
8
+ end
9
+
10
+ After('@selenium') do |scenario|
11
+ if !TestingBot.get_config[:client_key].nil?
12
+ begin
13
+ driver = ::Capybara.current_session.driver
14
+ if driver.browser.respond_to?(:session_id)
15
+ session_id = driver.browser.session_id
16
+ else
17
+ session_id = driver.browser.instance_variable_get("@bridge").instance_variable_get("@session_id")
18
+ end
19
+
20
+ api = TestingBot::Api.new
21
+ params = {
22
+ "session_id" => session_id,
23
+ "status_message" => (scenario.failed? ? scenario.exception.message : ""),
24
+ "success" => !scenario.failed? ? 1 : 0,
25
+ "name" => scenario.title,
26
+ "kind" => 2
27
+ }
28
+
29
+ data = api.update_test(session_id, params)
30
+ rescue Exception => e
31
+ p "Could not determine sessionID, can not send results to TestingBot.com #{e.message}"
32
+ end
33
+ end
34
+ end
30
35
  end
@@ -0,0 +1,255 @@
1
+ # rspec 1
2
+ if defined?(Spec) && defined?(Spec::VERSION::MAJOR) && Spec::VERSION::MAJOR == 1
3
+ require "selenium/rspec/spec_helper"
4
+ Spec::Runner.configure do |config|
5
+ config.before(:suite) do
6
+ if TestingBot.get_config[:require_tunnel]
7
+ @@tunnel = TestingBot::Tunnel.new(TestingBot.get_config[:tunnel_options] || {})
8
+ @@tunnel.start
9
+ end
10
+ end
11
+
12
+ config.after(:suite) do
13
+ @@tunnel.stop if defined? @@tunnel
14
+ end
15
+
16
+ config.prepend_after(:each) do
17
+ client_key = TestingBot.get_config[:client_key]
18
+ client_secret = TestingBot.get_config[:client_secret]
19
+
20
+ if !client_key.nil?
21
+
22
+ session_id = nil
23
+
24
+ if !@selenium_driver.nil?
25
+ session_id = @selenium_driver.session_id_backup
26
+ elsif defined?(Capybara)
27
+ begin
28
+ if page.driver.browser.respond_to?(:session_id)
29
+ session_id = page.driver.browser.session_id
30
+ else
31
+ session_id = page.driver.browser.instance_variable_get("@bridge").instance_variable_get("@session_id")
32
+ end
33
+ rescue Exception => e
34
+ puts "Could not determine sessionID, can not send results to TestingBot.com #{e.message}"
35
+ end
36
+ end
37
+
38
+ if !session_id.nil?
39
+ api = TestingBot::Api.new
40
+ params = {
41
+ "session_id" => session_id,
42
+ "status_message" => @execution_error,
43
+ "success" => !actual_failure? ? 1 : 0,
44
+ "name" => description.to_s,
45
+ "kind" => 2
46
+ }
47
+
48
+ data = api.update_test(session_id, params)
49
+
50
+ if ENV['JENKINS_HOME'] && (TestingBot.get_config[:jenkins_output] == true)
51
+ puts "TestingBotSessionID=" + session_id
52
+ end
53
+ end
54
+ else
55
+ puts "Can't post test results to TestingBot since I could not a .testingbot file in your home-directory."
56
+ end
57
+ end
58
+ end
59
+ end
60
+
61
+ # rspec 2
62
+ begin
63
+ require 'rspec'
64
+
65
+ ::RSpec.configuration.before :suite do
66
+ if TestingBot.get_config[:require_tunnel]
67
+ @@tunnel = TestingBot::Tunnel.new(TestingBot.get_config[:tunnel_options] || {})
68
+ @@tunnel.start
69
+ end
70
+ end
71
+
72
+ module TestingBot
73
+ module RSpecInclude
74
+ attr_reader :selenium_driver
75
+ alias_method :page, :selenium_driver
76
+
77
+ def self.included(base)
78
+ base.around do |test|
79
+ if TestingBot.get_config.desired_capabilities.instance_of?(Array)
80
+ TestingBot.get_config.desired_capabilities.each do |browser|
81
+ @selenium_driver = TestingBot::SeleniumWebdriver.new({ :desired_capabilities => browser })
82
+ begin
83
+ test.run
84
+ ensure
85
+ @selenium_driver.stop
86
+ end
87
+ end
88
+ else
89
+ @selenium_driver = TestingBot::SeleniumWebdriver.new({ :desired_capabilities => TestingBot.get_config.desired_capabilities })
90
+ begin
91
+ test.run
92
+ ensure
93
+ @selenium_driver.stop
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end
99
+
100
+ module RSpecIncludeLegacy
101
+ attr_reader :selenium_driver
102
+ alias_method :page, :selenium_driver
103
+
104
+ def self.included(base)
105
+ base.around do |test|
106
+ if TestingBot.get_config.desired_capabilities.instance_of?(Array)
107
+ TestingBot.get_config.desired_capabilities.each do |browser|
108
+ @selenium_driver = ::Selenium::Client::Driver.new(:browser => browser[:browserName], :url => TestingBot.get_config[:browserUrl])
109
+ @selenium_driver.start_new_browser_session(browser)
110
+ begin
111
+ test.run
112
+ ensure
113
+ @selenium_driver.stop
114
+ end
115
+ end
116
+ else
117
+ @selenium_driver = ::Selenium::Client::Driver.new(:browser => browser[:browserName], :url => TestingBot.get_config[:browserUrl])
118
+ @selenium_driver.start_new_browser_session(TestingBot.get_config.desired_capabilities)
119
+ begin
120
+ test.run
121
+ ensure
122
+ @selenium_driver.stop
123
+ end
124
+ end
125
+ end
126
+ end
127
+ end
128
+ end
129
+
130
+ ::RSpec.configuration.include(TestingBot::RSpecIncludeLegacy, :multibrowserRC => true)
131
+ ::RSpec.configuration.include(TestingBot::RSpecInclude, :multibrowser => true)
132
+
133
+ ::RSpec.configuration.after :suite do
134
+ @@tunnel.stop if defined? @@tunnel
135
+ end
136
+
137
+ ::RSpec.configuration.after :each do
138
+ client_key = TestingBot.get_config[:client_key]
139
+ client_secret = TestingBot.get_config[:client_secret]
140
+
141
+ if !client_key.nil?
142
+ test_name = ""
143
+ if example.metadata && example.metadata[:example_group]
144
+ if example.metadata[:example_group][:description_args]
145
+ test_name = example.metadata[:example_group][:description_args].join(" ")
146
+ end
147
+
148
+ if example.metadata[:description_args]
149
+ test_name = test_name + " it " + example.metadata[:description_args].join(" ")
150
+ end
151
+ end
152
+
153
+ status_message = ""
154
+ status_message = example.exception.to_s if !example.exception.nil?
155
+
156
+ session_id = nil
157
+
158
+ if !@selenium_driver.nil?
159
+ session_id = @selenium_driver.session_id
160
+ elsif defined? page
161
+ begin
162
+ if page.driver.browser.respond_to?(:session_id)
163
+ session_id = page.driver.browser.session_id
164
+ else
165
+ session_id = page.driver.browser.instance_variable_get("@bridge").instance_variable_get("@session_id")
166
+ end
167
+ rescue Exception => e
168
+ p "Could not determine sessionID, can not send results to TestingBot.com #{e.message}"
169
+ end
170
+ end
171
+
172
+ if !session_id.nil?
173
+ if ENV['JENKINS_HOME'] && (TestingBot.get_config[:jenkins_output] == true)
174
+ puts "TestingBotSessionID=" + session_id
175
+ end
176
+ api = TestingBot::Api.new
177
+ params = {
178
+ "session_id" => session_id,
179
+ "status_message" => status_message,
180
+ "success" => example.exception.nil? ? 1 : 0,
181
+ "name" => test_name,
182
+ "kind" => 2
183
+ }
184
+
185
+ data = api.update_test(session_id, params)
186
+ end
187
+ else
188
+ puts "Can't post test results to TestingBot since I could not a .testingbot file in your home-directory."
189
+ end
190
+ end
191
+ rescue LoadError
192
+ end
193
+
194
+ module TestingBot
195
+ module SeleniumForTestUnit
196
+ attr_accessor :exception
197
+ attr_reader :browser
198
+
199
+ def run(*args, &blk)
200
+ if TestingBot.get_config.desired_capabilities.instance_of?(Array)
201
+ TestingBot.get_config.desired_capabilities.each do |browser|
202
+ @browser = ::Selenium::Client::Driver.new(:browser => browser[:browserName], :url => TestingBot.get_config[:browserUrl])
203
+ @browser.start_new_browser_session(browser)
204
+ super(*args, &blk)
205
+ @browser.stop
206
+ end
207
+ else
208
+ super(*args, &blk)
209
+ end
210
+ end
211
+
212
+ def teardown
213
+ api = TestingBot::Api.new
214
+ params = {
215
+ "session_id" => browser.session_id,
216
+ "status_message" => @exception || "",
217
+ "success" => passed? ? 1 : 0,
218
+ "name" => self.to_s,
219
+ "kind" => 2
220
+ }
221
+
222
+ data = api.update_test(browser.session_id, params)
223
+
224
+ if ENV['JENKINS_HOME'] && (TestingBot.get_config[:jenkins_output] == true)
225
+ puts "TestingBotSessionID=" + browser.session_id
226
+ end
227
+ super
228
+ end
229
+
230
+ def handle_exception(e)
231
+ @exception = e.to_s
232
+ handle_exception_old(e)
233
+ end
234
+
235
+ alias :handle_exception_old :handle_exception
236
+ end
237
+ end
238
+
239
+ begin
240
+ require 'test/unit/testcase'
241
+ module TestingBot
242
+ class TestCase < Test::Unit::TestCase
243
+ include SeleniumForTestUnit
244
+ end
245
+ end
246
+ rescue LoadError
247
+ end
248
+
249
+ if defined?(ActiveSupport::TestCase)
250
+ module TestingBot
251
+ class RailsTestCase < ::ActiveSupport::TestCase
252
+ include SeleniumForTestUnit
253
+ end
254
+ end
255
+ end
@@ -0,0 +1,122 @@
1
+ # we create our own Selenium classes here to extend them with user credentials and config
2
+
3
+ require 'selenium/client'
4
+ require 'selenium/webdriver'
5
+ require 'selenium/webdriver/remote/http/persistent'
6
+
7
+ module TestingBot
8
+
9
+ class SeleniumWebdriver
10
+
11
+ attr_reader :config, :driver
12
+ attr_accessor :session_id_backup
13
+
14
+ def initialize(options = {})
15
+ @options = TestingBot::get_config.options
16
+ @options = @options.merge(options)
17
+
18
+ http_client = ::Selenium::WebDriver::Remote::Http::Persistent.new
19
+ http_client.timeout = 400
20
+ @driver = ::Selenium::WebDriver.for(:remote, :url => "http://#{@options[:client_key]}:#{@options[:client_secret]}@#{@options[:host]}:#{@options[:port]}/wd/hub", :desired_capabilities => @options[:desired_capabilities], :http_client => http_client)
21
+ http_client.timeout = 120
22
+ end
23
+
24
+ def method_missing(meth, *args)
25
+ @driver.send(meth, *args)
26
+ end
27
+
28
+ def session_id
29
+ @driver.send(:bridge).session_id
30
+ end
31
+
32
+ def stop
33
+ @session_id_backup = session_id
34
+ @driver.quit
35
+ end
36
+ end
37
+ end
38
+
39
+ # if selenium RC, add testingbot credentials to request
40
+ if defined?(Selenium) && defined?(Selenium::Client) && defined?(Selenium::Client::Protocol)
41
+ module Selenium
42
+ module Client
43
+ module Protocol
44
+ # add custom parameters for testingbot.com
45
+ def http_request_for_testingbot(verb, args)
46
+ data = http_request_for_original(verb, args)
47
+ data << "&client_key=#{TestingBot.get_config[:client_key]}&client_secret=#{TestingBot.get_config[:client_secret]}" unless TestingBot.get_config[:client_key].nil?
48
+ end
49
+
50
+ begin
51
+ alias http_request_for_original http_request_for
52
+ alias http_request_for http_request_for_testingbot
53
+ rescue
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+
60
+ if defined?(Selenium) && defined?(Selenium::Client) && defined?(Selenium::Client::Base)
61
+ module Selenium
62
+ module Client
63
+ module Base
64
+ DEFAULT_OPTIONS = {
65
+ :screenshot => true
66
+ }
67
+
68
+ alias :close_current_browser_session_old :close_current_browser_session
69
+ alias :start_new_browser_session_old :start_new_browser_session
70
+ alias :initialize_old :initialize
71
+
72
+ attr_accessor :options
73
+ attr_accessor :session_id_backup
74
+ attr_accessor :extra
75
+ attr_accessor :platform
76
+ attr_accessor :version
77
+
78
+ attr_reader :config
79
+
80
+ def initialize(*args)
81
+ @config = TestingBot::get_config
82
+ @options = @config[:options] || {}
83
+
84
+ if args[0].kind_of?(Hash)
85
+ options = args[0]
86
+ @platform = options[:platform] || "WINDOWS"
87
+ @version = options[:version] if options[:version]
88
+ end
89
+
90
+ @options = DEFAULT_OPTIONS
91
+ initialize_old(*args)
92
+ @host = options[:host] || @config[:host]
93
+ @port = options[:port] || @config[:port]
94
+ end
95
+
96
+ def close_current_browser_session
97
+ @session_id_backup = @session_id
98
+ close_current_browser_session_old
99
+ end
100
+
101
+ def session_id
102
+ @session_id || @session_id_backup || ""
103
+ end
104
+
105
+ def start_new_browser_session(options={})
106
+ options = @options.merge options
107
+ options[:platform] = @platform
108
+ options[:version] = @version unless @version.nil?
109
+ start_new_browser_session_old(options)
110
+ end
111
+
112
+ def extra=(str)
113
+ @extra = str
114
+ end
115
+
116
+ def options=(opts = {})
117
+ @options = @options.merge opts
118
+ end
119
+ end
120
+ end
121
+ end
122
+ end
@@ -1,16 +1,104 @@
1
1
  module TestingBot
2
- module Tunnel
3
- def self.start_tunnel(host, port, localport = 80)
4
- @@pid = fork do
5
- exec "ssh -gNR #{port}:localhost:#{localport} #{host}"
2
+ class Tunnel
3
+ TIMEOUT_SECONDS = 70
4
+
5
+ @@running = false
6
+
7
+ attr_reader :options, :config, :process, :available, :connected, :errors
8
+
9
+ def initialize(opts = {})
10
+ @available = false
11
+ @errors = []
12
+ @config = TestingBot.get_config
13
+ @options = default_options
14
+ @options = @options.merge(opts)
15
+
16
+ raise ArgumentError, "Please make sure you have put the .testingbot file in the your user directory, or set the environment variables TESTINGBOT_CLIENTKEY AND TESTINGBOT_CLIENTSECRET" if @config[:client_key].nil? || @config[:client_secret].nil?
17
+ end
18
+
19
+ def start
20
+ return if @@running == true
21
+
22
+ @@running = true
23
+
24
+ @config.require_tunnel
25
+ p "Starting the TestingBot Tunnel" if @options[:verbose] == true
26
+ @process = IO.popen("exec java -jar #{get_jar_path} #{@options[:client_key] || @config[:client_key]} #{@options[:client_secret] || @config[:client_secret]} #{extra_options} 2>&1")
27
+ at_exit do
28
+ @@running = false
29
+ # make sure we kill the tunnel
30
+ Process.kill("INT", @process.pid) if @available == true
6
31
  end
32
+
33
+ Thread.new do
34
+ while (line = @process.gets)
35
+ if line =~ /^You may start your tests/
36
+ @available = true
37
+ end
38
+
39
+ if line =~ /Exception/ || line =~ /error/
40
+ @errors << line
41
+ end
42
+
43
+ p line if @options[:verbose] == true
44
+ end
45
+ end
46
+
47
+ poll_ready
48
+
49
+ p "You are now ready to start your test" if @options[:verbose] == true
50
+ end
51
+
52
+ def is_connected?
53
+ @available
7
54
  end
8
55
 
9
- def self.stop_tunnel
10
- if @@pid
11
- Process.kill "TERM", @@pid
12
- Process.wait @@pid
56
+ def errors
57
+ @errors || []
58
+ end
59
+
60
+ def stop
61
+ raise "Can't stop tunnel, it has not been started yet" if @process.nil?
62
+ p "Stopping TestingBot Tunnel" if @options[:verbose] == true
63
+
64
+ kill
65
+ end
66
+
67
+ def kill
68
+ @@running = false
69
+ @available = false
70
+ Process.kill("INT", @process.pid)
71
+ Process.wait
72
+ end
73
+
74
+ def extra_options
75
+ extra = @options[:options] || []
76
+ extra.join(" ")
77
+ end
78
+
79
+ private
80
+
81
+ def default_options
82
+ {
83
+ :verbose => true
84
+ }
85
+ end
86
+
87
+ def get_jar_path
88
+ file = File.expand_path(File.dirname(__FILE__) + '/../../vendor/Testingbot-Tunnel.jar')
89
+ raise RuntimeException, "Could not find TestingBot-Tunnel.jar in vendor directory" unless File.exists?(file)
90
+
91
+ file
92
+ end
93
+
94
+ def poll_ready
95
+ seconds = 0
96
+ while ((@available == false) && (seconds < TIMEOUT_SECONDS) && @errors.empty?)
97
+ sleep 1
98
+ seconds = seconds + 1
13
99
  end
100
+
101
+ raise "Could not start Tunnel after #{TIMEOUT_SECONDS} seconds" if !is_connected? && @errors.empty?
14
102
  end
15
103
  end
16
104
  end