selenium-client 1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,95 @@
1
+ module Selenium
2
+ module Client
3
+
4
+ HTTP_HEADERS = { 'Content-Type' => 'application/x-www-form-urlencoded; charset=utf-8' }
5
+
6
+ module SeleneseClient
7
+ attr_reader :session_id
8
+
9
+ def do_command(verb, args)
10
+ timeout(@timeout) do
11
+ status, response = http_post(http_request_for(verb, args))
12
+ raise SeleniumCommandError, response unless status == "OK"
13
+ response
14
+ end
15
+ end
16
+
17
+ def get_string(verb, args)
18
+ do_command(verb, args)
19
+ end
20
+
21
+ def get_string_array(verb, args)
22
+ csv = get_string(verb, args)
23
+ token = ""
24
+ tokens = []
25
+ escape = false
26
+ csv.split(//).each do |letter|
27
+ if escape
28
+ token += letter
29
+ escape = false
30
+ next
31
+ end
32
+ case letter
33
+ when '\\'
34
+ escape = true
35
+ when ','
36
+ tokens << token
37
+ token = ""
38
+ else
39
+ token += letter
40
+ end
41
+ end
42
+ tokens << token
43
+ return tokens
44
+ end
45
+
46
+ def get_number(verb, args)
47
+ # Is there something I need to do here?
48
+ return get_string(verb, args)
49
+ end
50
+
51
+ def get_number_array(verb, args)
52
+ # Is there something I need to do here?
53
+ return get_string_array(verb, args)
54
+ end
55
+
56
+ def get_boolean(verb, args)
57
+ parse_boolean_value get_string(verb, args)
58
+ end
59
+
60
+ def get_boolean_array(verb, args)
61
+ get_string_array(verb, args).collect {|value| parse_boolean_value(value)}
62
+ end
63
+
64
+ protected
65
+
66
+ def parse_boolean_value(value)
67
+ if ("true" == value)
68
+ return true
69
+ elsif ("false" == value)
70
+ return false
71
+ end
72
+ raise ProtocolError, "Invalid Selenese boolean value that is neither 'true' nor 'false': got '#{value}'"
73
+ end
74
+
75
+ def http_request_for(verb, args)
76
+ data = "cmd=#{CGI::escape(verb)}"
77
+ args.each_with_index do |arg, index|
78
+ data << "&#{index.succ}=#{CGI::escape(arg.to_s)}"
79
+ end
80
+ data << "&sessionId=#{session_id}" unless session_id.nil?
81
+ data
82
+ end
83
+
84
+ def http_post(data)
85
+ #print "Requesting --->" + command_string + "\n"
86
+ http = Net::HTTP.new(@server_host, @server_port)
87
+ response = http.post('/selenium-server/driver/', data, HTTP_HEADERS)
88
+ #print "RESULT: " + response.body + "\n\n"å
89
+ [ response.body[0..1], response.body[3..-1] ]
90
+ end
91
+
92
+ end
93
+
94
+ end
95
+ end
@@ -0,0 +1,36 @@
1
+ # Defines a mixin module that you can use to write Selenium tests
2
+ # without typing "@selenium." in front of every command. Every
3
+ # call to a missing method will be automatically sent to the @selenium
4
+ # object.
5
+ module Selenium
6
+ module Client
7
+
8
+ module SeleniumHelper
9
+
10
+ # Overrides standard "open" method with @selenium.open
11
+ def open(addr)
12
+ @selenium.open(addr)
13
+ end
14
+
15
+ # Overrides standard "type" method with @selenium.type
16
+ def type(inputLocator, value)
17
+ @selenium.type(inputLocator, value)
18
+ end
19
+
20
+ # Overrides standard "select" method with @selenium.select
21
+ def select(inputLocator, optionLocator)
22
+ @selenium.select(inputLocator, optionLocator)
23
+ end
24
+
25
+ # Passes all calls to missing methods to @selenium
26
+ def method_missing(method_name, *args)
27
+ if args.empty?
28
+ @selenium.send(method_name)
29
+ else
30
+ @selenium.send(method_name, *args)
31
+ end
32
+ end
33
+ end
34
+
35
+ end
36
+ end
@@ -0,0 +1,4 @@
1
+ module Selenium
2
+ class CommandError < RuntimeError
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module Selenium
2
+ class ProtocolError < RuntimeError
3
+ end
4
+ end
@@ -0,0 +1,187 @@
1
+ require "digest/md5"
2
+ require "base64"
3
+ require "rubygems"
4
+ require "spec"
5
+ require 'spec/runner/formatter/html_formatter'
6
+
7
+ module Selenium
8
+ module RSpec
9
+ class ScreenshotFormatter < Spec::Runner::Formatter::HtmlFormatter
10
+ PLACEHOLDER = "<<placeholder>>"
11
+
12
+ ################### Hooks? ########
13
+
14
+ def start(example_count)
15
+ super
16
+ # ensure there's at least 1 example group header (normally 0 with deep_test)
17
+ # prevents js and html validity errors
18
+ example_group = Object.new
19
+ def example_group.description; ""; end
20
+ add_example_group(example_group)
21
+ end
22
+
23
+ def move_progress
24
+ # we don't have current_example_number, and we don't really care about the progress bar
25
+ end
26
+
27
+ def extra_failure_content(failure)
28
+ super + PLACEHOLDER
29
+ end
30
+
31
+ def example_passed(example)
32
+ include_example_group_description example
33
+ super
34
+ end
35
+
36
+ def example_pending(example_group_description, example, message)
37
+ include_example_group_description example
38
+ super
39
+ end
40
+
41
+ def example_failed(example, counter, failure)
42
+ include_example_group_description example
43
+ old_output = @output
44
+ @output = StringIO.new
45
+ super
46
+ result = @output.string
47
+ result.gsub! PLACEHOLDER, html_capture(example)
48
+ old_output.puts result
49
+ old_output.flush
50
+ ensure
51
+ @output = old_output
52
+ end
53
+
54
+
55
+ ###### Called from After each ####
56
+
57
+ def self.capture_browser_state(selenium_driver, example)
58
+ # Selenium RC seems to 'freeze' every so often when calling getHTMLSource, especially when DeepTest timeout is low, I need to investigate...
59
+ # Set deeptest :timeout_in_seconds => 30 to see it happen
60
+ capture_html_snapshot selenium_driver, example
61
+ capture_screenshot selenium_driver, example
62
+ end
63
+
64
+ def self.capture_html_snapshot(selenium_driver, example)
65
+ html = selenium_driver.get_html_source
66
+ File.open(file_for_html_capture(example), "w") { |f| f.write html }
67
+ end
68
+
69
+ def self.capture_screenshot(selenium_driver, example)
70
+ selenium_driver.window_maximize
71
+ encodedImage = selenium_driver.capture_screenshot_to_string
72
+ pngImage = Base64.decode64(encodedImage)
73
+ File.open(file_for_screenshot_capture(example), "w") { |f| f.write pngImage }
74
+ end
75
+
76
+ ################### Instrumentation ########
77
+
78
+ def html_capture(example)
79
+ dom_id = "example_" + self.class.hash_for_example(example)
80
+ screenshot_url = self.class.relative_file_for_png_capture(example)
81
+ snapshot_url = self.class.relative_file_for_html_capture(example)
82
+ <<-EOS
83
+ <div>[<a id="#{dom_id}_screenshot_link" href="javascript:toggleVisilibility('#{dom_id}_screenshot', 'Screenshot');">Show screenshot</a>]</div>
84
+ <br/>
85
+ <div id="#{dom_id}_screenshot" style="display: none">
86
+ <a href="#{screenshot_url}">
87
+ <img width="80%" src="#{screenshot_url}" />
88
+ </a>
89
+ </div>
90
+ <br/>
91
+
92
+ <div>[<a id="#{dom_id}_snapshot_link" href=\"javascript:toggleVisilibility('#{dom_id}_snapshot', 'Snapshot')\">Show snapshot</a>]</div>
93
+ <br/><br/>
94
+ <div id="#{dom_id}_snapshot" class="dyn-source">
95
+ <a href="#{snapshot_url}">Full screen</a><br/><br/>
96
+ <iframe src="#{snapshot_url}" width="100%" height="600px" ></iframe>
97
+ </div>
98
+ EOS
99
+ end
100
+
101
+
102
+ def self.relative_file_for_html_capture(example)
103
+ "resources/example_#{hash_for_example(example)}.html"
104
+ end
105
+
106
+ def self.relative_file_for_png_capture(example)
107
+ "resources/example_#{hash_for_example(example)}.png"
108
+ end
109
+
110
+ def self.file_for_html_capture(example)
111
+ file_name = capture_root_dir + "/example_#{hash_for_example(example)}.html"
112
+ FileUtils.mkdir_p(capture_root_dir) unless File.directory?(capture_root_dir)
113
+ file_name
114
+ end
115
+
116
+ def self.file_for_screenshot_capture(example)
117
+ file_name = capture_root_dir + "/example_#{hash_for_example(example)}.png"
118
+ FileUtils.mkdir_p(capture_root_dir) unless File.directory?(capture_root_dir)
119
+ file_name
120
+ end
121
+
122
+ def self.hash_for_example(example)
123
+ Digest::MD5.hexdigest example.implementation_backtrace.first
124
+ end
125
+
126
+
127
+ def self.capture_root_dir
128
+ root_dir + "/resources"
129
+ end
130
+
131
+ def self.root_dir
132
+ (ENV['CC_BUILD_ARTIFACTS'] || './tmp/rspec_report')
133
+ end
134
+
135
+
136
+ def include_example_group_description(example)
137
+ def example.description
138
+ self.class.description.to_s + " :: " + super
139
+ end
140
+ end
141
+
142
+
143
+ def report_header
144
+ super + "\n<script type=\"text/javascript\">moveProgressBar('100.0');</script>"
145
+ end
146
+
147
+
148
+
149
+ def global_scripts
150
+ super + <<-EOF
151
+ function toggleVisilibility(id, description) {
152
+ var section;
153
+ var link;
154
+
155
+ section = document.getElementById(id);
156
+ link = document.getElementById(id + "_link");
157
+
158
+ if (section.style.display == "block") {
159
+ section.style.display = "none"
160
+ link.innerHTML = description
161
+ } else {
162
+ section.style.display = "block"
163
+ link.innerHTML = "Hide " + description
164
+ }
165
+ }
166
+ EOF
167
+ end
168
+
169
+ def global_styles
170
+ super + <<-EOF
171
+ div.rspec-report textarea {
172
+ width: 100%;
173
+ }
174
+
175
+ div.rspec-report .dyn-source {
176
+ background: #FFFFEE none repeat scroll 0%;
177
+ border:1px dotted black;
178
+ color: #000000;
179
+ display: none;
180
+ margin: 0.5em 2em;
181
+ padding: 0.5em;
182
+ }
183
+ EOF
184
+ end
185
+ end
186
+ end
187
+ end
@@ -0,0 +1,25 @@
1
+ module Selenium
2
+ module ScreenshotSaver
3
+
4
+ def save_screenshot_to(png_path)
5
+ dir = File.dirname(png_path)
6
+ FileUtils.mkdir_p(dir) unless File.directory?(dir)
7
+ if PLATFORM['darwin']
8
+ sh "screencapture '#{png_path}'"
9
+ elsif image_magick_support?
10
+ sh "import -window root '#{png_path}'"
11
+ end
12
+ end
13
+
14
+ def image_magick_support?
15
+ @image_magick_support ||= `import --version`.grep /"ImageMagick"/
16
+ end
17
+
18
+ def sh(command)
19
+ system command
20
+ STDERR.puts "Warning: Could not capture screenshot with '#{command}'" unless $? == 0
21
+ end
22
+
23
+ end
24
+
25
+ end
@@ -0,0 +1,3 @@
1
+ Dir["#{File.dirname __FILE__}/unit/**/*_test.rb"].each do |test_case|
2
+ require test_case
3
+ end
metadata ADDED
@@ -0,0 +1,67 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: selenium-client
3
+ version: !ruby/object:Gem::Version
4
+ version: "1.1"
5
+ platform: ruby
6
+ authors:
7
+ - OpenQA
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-07-16 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description:
17
+ email: selenium-client@rubyforge.org
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README
24
+ files:
25
+ - lib/selenium/client/base.rb
26
+ - lib/selenium/client/driver.rb
27
+ - lib/selenium/client/generated_driver.rb
28
+ - lib/selenium/client/selenese_client.rb
29
+ - lib/selenium/client/selenium_helper.rb
30
+ - lib/selenium/command_error.rb
31
+ - lib/selenium/protocol_error.rb
32
+ - lib/selenium/rspec/screenshot_formatter.rb
33
+ - lib/selenium/screenshot_saver.rb
34
+ - lib/selenium.rb
35
+ - README
36
+ has_rdoc: true
37
+ homepage: http://selenium-client.rubyforge.com
38
+ post_install_message:
39
+ rdoc_options:
40
+ - --title
41
+ - Selenium Client
42
+ - --main
43
+ - README
44
+ - --line-numbers
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: "0"
52
+ version:
53
+ required_rubygems_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: "0"
58
+ version:
59
+ requirements: []
60
+
61
+ rubyforge_project: selenium-client
62
+ rubygems_version: 1.2.0
63
+ signing_key:
64
+ specification_version: 2
65
+ summary: Official Ruby Client for Selenium RC.
66
+ test_files:
67
+ - test/all_unit_tests.rb