testingbot 0.0.9 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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