selenium_shots 0.2.4 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -3,6 +3,53 @@
3
3
  http://www.seleniumshots.com
4
4
  Selenium Shots is an Integration Testing Service that transparently distributes your integration tests across multiple operating systems with different versions of all major browsers AND captures a screen shot. This eliminates the need to have multiple vm's on your computer or the need for multiple machines on your test to test your web application. Running your tests remotely will dramatically speed up in-browser web testing and leave more time to and create a slide show available to confirm visuals making it easy for you to improve your web application.
5
5
 
6
+ == Install
7
+
8
+ === Rails 3
9
+
10
+ Add this to your Gemfile:
11
+
12
+ group :development do
13
+ gem 'selenium_shots'
14
+ end
15
+
16
+ === Rails 2
17
+
18
+ To install add teh following to config/environment.rb:
19
+
20
+ config.gem 'selenium_shots'
21
+
22
+ == Configure
23
+
24
+ In configure/selenium_shots.yml you will need to define the application
25
+ * api_key
26
+ * mode
27
+ * default_browser_url
28
+ * application_name
29
+ * local_browser
30
+ * browsers
31
+
32
+ == Creating Tests
33
+
34
+
35
+ class MyTest < SeleniumShots
36
+
37
+ @group = "MyTestGroup"
38
+
39
+ selenium_shot "Should run my test and pass." do
40
+ @name = "My Test Name"
41
+ browser.open "/my_site"
42
+ browser.type "search[query]", "Cats"
43
+ browser.click "find"
44
+ end
45
+ end
46
+
47
+ == Selenium Setup
48
+ Download the latest version of selenium grid from http://seleniumhq.org/download/
49
+
50
+ ===Using a Custom Selenium Server
51
+ `ant launch-remote-control -DcustomRemoteControl=/path/to/your/customer/selenium-server.jar`
52
+
6
53
  == Copyright
7
54
 
8
55
  Copyright (c) 2010 Kyle Ginavan. See LICENSE for details.
data/examples/google.rb CHANGED
@@ -5,11 +5,10 @@ class Google < SeleniumShots
5
5
  @group = "Google"
6
6
 
7
7
  selenium_shot "should search on google" do
8
- @name = "selenium shots"
9
- browser.open "/"
10
- browser.type "q", "Selenium Shots"
11
- browser.click "btnG"
8
+ @name = "Google search"
9
+ element = driver.find_element(:name, 'q')
10
+ element.send_keys "Hello WebDriver!"
11
+ element.submit
12
12
  end
13
-
14
13
  end
15
14
 
@@ -7,7 +7,7 @@ class SeleniumShots::Client
7
7
 
8
8
  attr_reader :host, :api_key
9
9
 
10
- def initialize(api_key, host='seleniumshots.com')
10
+ def initialize(api_key, host='www.seleniumshots.com')
11
11
  @api_key = api_key
12
12
  @host = host
13
13
  end
@@ -15,8 +15,8 @@ module SeleniumShots::Command
15
15
  end
16
16
 
17
17
  def get_api_key_from_host
18
- RestClient.post 'http://seleniumshots.com/selenium_tests/get_api_key', :user_session => { :email => @api_key_hash[0],
19
- :password => @api_key_hash[1]}
18
+ RestClient.post 'http://www.seleniumshots.com/selenium_tests/get_api_key', :user_session => { :email => @api_key_hash[0],
19
+ :password => @api_key_hash[1]}
20
20
  end
21
21
 
22
22
  def api_key_file
@@ -57,7 +57,7 @@ api_key: "#{api_key}"
57
57
  mode: "remote" # "local" for run test locally
58
58
  default_browser_url: "http://www.myapp.com"
59
59
  application_name: "#{name}"
60
- local_browser: "*firefox3"
60
+ local_browser: "firefox"
61
61
  browsers:
62
62
  - IE8 on XP
63
63
  - Firefox3.6 on XP
@@ -1,6 +1,7 @@
1
1
  require "test/unit"
2
2
  require "rubygems"
3
3
  require "selenium/client"
4
+ require "selenium-webdriver"
4
5
  require 'active_support'
5
6
  require 'active_support/test_case'
6
7
  require 'ostruct'
@@ -17,7 +18,7 @@ end
17
18
 
18
19
  class SeleniumShots < ActionController::IntegrationTest
19
20
 
20
- attr_reader :browser, :agent
21
+ attr_reader :driver, :agent, :take_screenshot
21
22
  cattr_accessor :expected_test_count
22
23
 
23
24
  if SeleniumConfig.mode == "remote"
@@ -36,7 +37,7 @@ class SeleniumShots < ActionController::IntegrationTest
36
37
  end
37
38
 
38
39
  def local_browsers
39
- ["*firefox3", "*iexplore", "*safari"]
40
+ ["firefox", "ie", "chrome"]
40
41
  end
41
42
 
42
43
  def selected_browsers
@@ -50,38 +51,20 @@ class SeleniumShots < ActionController::IntegrationTest
50
51
  end
51
52
  end
52
53
  end
53
-
54
- def setup
55
- if(not self.class.expected_test_count)
56
- self.class.expected_test_count = (self.class.instance_methods.reject{|method| method[0..3] != 'test'}).length
57
- if SeleniumConfig.mode == "local"
58
- FileUtils.rm(pid_file) if File.exists?(pid_file)
59
- IO.popen("selenium_shots_local_server start 2>&1")
60
- sleep(2)
61
- end
62
- end
63
- end
64
-
65
- def teardown
66
- if((self.class.expected_test_count-=1) == 0)
67
- if File.exists?(pid_file) && SeleniumConfig.mode == "local"
68
- IO.popen("selenium_shots_local_server stop 2>&1")
69
- end
70
- end
71
- end
72
-
73
- def self.selenium_shot(description, &block)
54
+
55
+ def self.core_test(description, take_screenshot = true, &block)
74
56
  @@group = (@group || "Default")
75
57
  test_name = "test_#{description.gsub(/\s+/,'_')}".to_sym
76
58
  defined = instance_method(test_name) rescue false
77
59
  raise "#{test_name} is already defined in #{self}" if defined
78
60
  if block_given?
79
- define_method(test_name) do
80
- @description = description
81
- run_in_all_browsers do |browser|
82
- instance_eval &block
83
- end
84
- end
61
+ define_method(test_name) do
62
+ @description = description
63
+ @take_screenshot = take_screenshot
64
+ run_in_all_browsers do
65
+ instance_eval &block
66
+ end
67
+ end
85
68
  else
86
69
  define_method(test_name) do
87
70
  flunk "No implementation provided for #{name}"
@@ -89,14 +72,22 @@ class SeleniumShots < ActionController::IntegrationTest
89
72
  end
90
73
  end
91
74
 
75
+ def self.selenium_test(description, &block)
76
+ core_test(description, nil, &block)
77
+ end
78
+
79
+ def self.selenium_shot(description, &block)
80
+ core_test(description, true, &block)
81
+ end
82
+
92
83
  def run_in_all_browsers(&block)
93
84
  @error = nil
94
85
  browsers = (@selected_browser || selected_browsers)
95
86
  browsers.each do |browser_spec|
96
87
  begin
97
- run_browser(browser_spec, block)
88
+ run_webdriver(browser_spec, block)
98
89
  rescue => error
99
- @browser.close_current_browser_session if @browser
90
+ @driver.quit if @driver
100
91
  @error = error.message
101
92
  if @error.match(/Failed to start new browser session/) && SeleniumConfig.mode == "local"
102
93
  @tmp_browsers ||= local_browsers
@@ -111,48 +102,76 @@ class SeleniumShots < ActionController::IntegrationTest
111
102
  end
112
103
  assert @error.nil?, "Expected zero failures or errors, but got #{@error}\n"
113
104
  end
105
+
106
+ def run_webdriver(browser_spec, block)
107
+
108
+ client = Selenium::WebDriver::Remote::Http::Default.new
109
+ client.timeout = 20 # seconds
110
+
111
+ if SeleniumConfig.mode == "local"
112
+ if /(firefox)/i.match(browser_spec)
113
+ profile = Selenium::WebDriver::Firefox::Profile.new
114
+ profile.native_events = false
115
+ @driver = Selenium::WebDriver.for(:firefox, :profile => profile, :http_client => client)
116
+ elsif /(chrome)/i.match(browser_spec)
117
+ @driver = Selenium::WebDriver.for(:chrome, :http_client => client)
118
+ elsif /(ie)/i.match(browser_spec)
119
+ @driver = Selenium::WebDriver.for(:ie, :http_client => client)
120
+ end
121
+ else
122
+ caps = nil
123
+ if /(firefox)/i.match(browser_spec)
124
+ caps = WebDriver::Remote::Capabilities.firefox
125
+ elsif /(chrome)/i.match(browser_spec)
126
+ caps = WebDriver::Remote::Capabilities.chrome
127
+ elsif /(ie)/i.match(browser_spec)
128
+ caps = WebDriver::Remote::Capabilities.internet_explorer
129
+ elsif /(safari)/i.match(browser_spec)
130
+ caps = WebDriver::Remote::Capabilities.safari
131
+ elsif /(htmlunit)/i.match(browser_spec)
132
+ caps = WebDriver::Remote::Capabilities.htmlunit
133
+ caps.javascript_enabled = true
134
+ end
135
+
136
+ @driver = Selenium::WebDriver.for(:remote, :desired_capabilities => caps, :http_client => client) if caps
137
+ end
138
+
139
+ @driver.manage.timeouts.implicit_wait = 2 #seconds
140
+ @driver.navigate.to SeleniumConfig.default_browser_url
114
141
 
115
- def run_browser(browser_spec, block)
116
- @browser = Selenium::Client::Driver.new(
117
- :host => HOST,
118
- :port => PORT,
119
- :browser => browser_spec,
120
- :url => SeleniumConfig.default_browser_url,
121
- :timeout_in_second => 200)
122
- @browser.start_new_browser_session
123
142
  begin
124
- block.call(@browser)
143
+ block.call
125
144
  rescue => error
126
145
  @error = error.message
146
+ puts @error
127
147
  ensure
128
148
  save_test({:selenium_test_group_name => @@group, :selenium_test_name => @name,
129
149
  :description => @description}) if SeleniumConfig.mode == "remote"
130
- @browser.close_current_browser_session
131
- end
150
+ @driver.quit
151
+ end
132
152
  end
133
153
 
134
154
  def capture_screenshot_on(src)
135
155
  browser.window_focus
136
156
  browser.window_maximize
137
157
  sleep(2)
138
- if browser.browser_string.match(/XP/)
139
- browser.capture_entire_page_screenshot("#{PICS_WINDOWS_PATH}\\#{src}", "background=#FFFFFF")
140
- elsif browser.browser_string.match(/SnowLeopard/)
141
- browser.capture_entire_page_screenshot("#{PICS_MACOS_PATH}/#{src}", "background=#FFFFFF")
142
- elsif browser.browser_string.match(/Linux/)
143
- browser.capture_entire_page_screenshot("#{PICS_LINUX_PATH}/#{src}", "background=#FFFFFF")
158
+ if @driver.browser.to_s.match(/XP/)
159
+ @driver.capture_entire_page_screenshot("#{PICS_WINDOWS_PATH}\\#{src}", "background=#FFFFFF")
160
+ elsif @driver.browser.to_s.match(/SnowLeopard/)
161
+ @driver.capture_entire_page_screenshot("#{PICS_MACOS_PATH}/#{src}", "background=#FFFFFF")
162
+ elsif @driver.browser.to_s.match(/Linux/)
163
+ @driver.capture_entire_page_screenshot("#{PICS_LINUX_PATH}/#{src}", "background=#FFFFFF")
144
164
  end
145
165
  end
146
166
 
147
167
  def save_test(params)
148
168
  src = "#{SeleniumConfig.application_name}_#{params[:selenium_test_group_name]}_#{params[:selenium_test_name]}_" +
149
- "#{browser.browser_string.gsub(/\s+/,"_").downcase}.png"
169
+ "#{@driver.browser.to_s.gsub(/\s+/,"_").downcase}.png"
150
170
 
151
171
  capture_screenshot_on(src)
152
172
 
153
173
  SeleniumTest.create(:selenium_test_name => params[:selenium_test_name], :description => params[:description],
154
- :url => browser.location, :error_message => @error, :is_error => !@error.nil?, :environment => browser.browser_string,
174
+ :url => @driver.current_url, :error_message => @error, :is_error => !@error.nil?, :environment => @driver.browser.to_s,
155
175
  :selenium_test_group_name => params[:selenium_test_group_name], :application_name => SeleniumConfig.application_name)
156
176
  end
157
177
  end
158
-
metadata CHANGED
@@ -3,10 +3,10 @@ name: selenium_shots
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
+ - 1
6
7
  - 0
7
- - 2
8
- - 4
9
- version: 0.2.4
8
+ - 0
9
+ version: 1.0.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Kyle J. Ginavan
@@ -15,8 +15,8 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-06-22 00:00:00 -05:00
19
- default_executable:
18
+ date: 2010-12-02 00:00:00 -06:00
19
+ default_executable: selenium_shots
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
22
  name: thoughtbot-shoulda
@@ -31,23 +31,37 @@ dependencies:
31
31
  type: :development
32
32
  version_requirements: *id001
33
33
  - !ruby/object:Gem::Dependency
34
- name: selenium-client
34
+ name: rspec
35
35
  prerelease: false
36
36
  requirement: &id002 !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "="
39
+ - !ruby/object:Gem::Version
40
+ segments:
41
+ - 1
42
+ - 1
43
+ - 12
44
+ version: 1.1.12
45
+ type: :development
46
+ version_requirements: *id002
47
+ - !ruby/object:Gem::Dependency
48
+ name: selenium-webdriver
49
+ prerelease: false
50
+ requirement: &id003 !ruby/object:Gem::Requirement
37
51
  requirements:
38
52
  - - ">="
39
53
  - !ruby/object:Gem::Version
40
54
  segments:
55
+ - 0
41
56
  - 1
42
- - 2
43
- - 18
44
- version: 1.2.18
57
+ - 0
58
+ version: 0.1.0
45
59
  type: :runtime
46
- version_requirements: *id002
60
+ version_requirements: *id003
47
61
  - !ruby/object:Gem::Dependency
48
62
  name: rest-client
49
63
  prerelease: false
50
- requirement: &id003 !ruby/object:Gem::Requirement
64
+ requirement: &id004 !ruby/object:Gem::Requirement
51
65
  requirements:
52
66
  - - ">="
53
67
  - !ruby/object:Gem::Version
@@ -57,12 +71,11 @@ dependencies:
57
71
  - 2
58
72
  version: 0.8.2
59
73
  type: :runtime
60
- version_requirements: *id003
74
+ version_requirements: *id004
61
75
  description: Selenium Shots is an Integration Testing Service that transparently distributes your integration tests across multiple operating systems with different versions of all major browsers AND captures a screen shot
62
76
  email: kyle@4rockets.com
63
77
  executables:
64
78
  - selenium_shots
65
- - selenium_shots_local_server
66
79
  extensions: []
67
80
 
68
81
  extra_rdoc_files:
@@ -77,10 +90,8 @@ files:
77
90
  - lib/selenium_shots/cli/commands/auth.rb
78
91
  - lib/selenium_shots/cli/commands/base.rb
79
92
  - lib/selenium_shots/cli/commands/help.rb
80
- - lib/selenium_shots/cli/commands/server.rb
81
93
  - lib/selenium_shots/cli/init.rb
82
94
  - lib/selenium_shots/test_selenium_shots.rb
83
- - vendor/selenium-server-1.0.2-SNAPSHOT-standalone.jar
84
95
  - LICENSE
85
96
  - LICENSE.orig
86
97
  - README.rdoc
@@ -1,16 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'rubygems'
4
- require 'fileutils'
5
-
6
- $LOAD_PATH.unshift(File.dirname(__FILE__) + '/../lib/selenium_shots/cli/')
7
-
8
- require 'init'
9
-
10
- args = ARGV.dup
11
- ARGV.clear
12
-
13
- command = args.shift.strip rescue 'help'
14
-
15
- SeleniumShots::Command.run("server:#{command}", args)
16
-
@@ -1,34 +0,0 @@
1
- module SeleniumShots::Command
2
- class Server < Base
3
-
4
- GEM_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '/../../../../'))
5
- SELENIUM_SERVER = File.join(GEM_ROOT, 'vendor', 'selenium-server-1.0.2-SNAPSHOT-standalone.jar')
6
-
7
- def pid_file
8
- '/tmp/selenium_shots.pid'
9
- end
10
-
11
- def start
12
- if File.exists?(pid_file)
13
- puts "the selenium shots server is running...."
14
- else
15
- pipe = IO.popen("java -jar #{SELENIUM_SERVER}")
16
- File.open(pid_file, 'w') {|f| f.write(pipe.pid) }
17
- end
18
- end
19
-
20
- def stop
21
- if File.exists?(pid_file)
22
- process_id = File.open(pid_file,'r').readline
23
- Process.kill 9, process_id.to_i
24
- FileUtils.rm(pid_file)
25
- end
26
- end
27
-
28
- def help
29
- puts "selenium_shots_local_server {start|stop}"
30
- end
31
-
32
- end
33
- end
34
-