celerity_thingista 0.9.2

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.
Files changed (118) hide show
  1. data/.document +5 -0
  2. data/.gitignore +9 -0
  3. data/.gitmodules +3 -0
  4. data/.travis.yml +4 -0
  5. data/Gemfile +3 -0
  6. data/LICENSE +278 -0
  7. data/README.rdoc +84 -0
  8. data/Rakefile +15 -0
  9. data/benchmark/bm_2000_spans.rb +48 -0
  10. data/benchmark/bm_digg.rb +26 -0
  11. data/benchmark/bm_google_images.rb +36 -0
  12. data/benchmark/bm_input_locator.rb +69 -0
  13. data/benchmark/bm_text_input.rb +19 -0
  14. data/benchmark/loader.rb +14 -0
  15. data/celerity.gemspec +26 -0
  16. data/lib/celerity.rb +75 -0
  17. data/lib/celerity/browser.rb +924 -0
  18. data/lib/celerity/clickable_element.rb +73 -0
  19. data/lib/celerity/collections.rb +164 -0
  20. data/lib/celerity/container.rb +802 -0
  21. data/lib/celerity/default_viewer.rb +14 -0
  22. data/lib/celerity/disabled_element.rb +40 -0
  23. data/lib/celerity/element.rb +314 -0
  24. data/lib/celerity/element_collection.rb +115 -0
  25. data/lib/celerity/element_locator.rb +164 -0
  26. data/lib/celerity/elements/button.rb +54 -0
  27. data/lib/celerity/elements/file_field.rb +29 -0
  28. data/lib/celerity/elements/form.rb +22 -0
  29. data/lib/celerity/elements/frame.rb +86 -0
  30. data/lib/celerity/elements/image.rb +89 -0
  31. data/lib/celerity/elements/label.rb +16 -0
  32. data/lib/celerity/elements/link.rb +43 -0
  33. data/lib/celerity/elements/meta.rb +14 -0
  34. data/lib/celerity/elements/non_control_elements.rb +124 -0
  35. data/lib/celerity/elements/option.rb +38 -0
  36. data/lib/celerity/elements/radio_check.rb +114 -0
  37. data/lib/celerity/elements/select_list.rb +146 -0
  38. data/lib/celerity/elements/table.rb +154 -0
  39. data/lib/celerity/elements/table_cell.rb +36 -0
  40. data/lib/celerity/elements/table_elements.rb +42 -0
  41. data/lib/celerity/elements/table_row.rb +54 -0
  42. data/lib/celerity/elements/text_field.rb +168 -0
  43. data/lib/celerity/exception.rb +83 -0
  44. data/lib/celerity/htmlunit.rb +64 -0
  45. data/lib/celerity/htmlunit/commons-codec-1.7.jar +0 -0
  46. data/lib/celerity/htmlunit/commons-collections-3.2.1.jar +0 -0
  47. data/lib/celerity/htmlunit/commons-io-2.4.jar +0 -0
  48. data/lib/celerity/htmlunit/commons-lang3-3.1.jar +0 -0
  49. data/lib/celerity/htmlunit/commons-logging-1.1.1.jar +0 -0
  50. data/lib/celerity/htmlunit/cssparser-0.9.9.jar +0 -0
  51. data/lib/celerity/htmlunit/htmlunit-2.12.jar +0 -0
  52. data/lib/celerity/htmlunit/htmlunit-core-js-2.12.jar +0 -0
  53. data/lib/celerity/htmlunit/httpclient-4.2.3.jar +0 -0
  54. data/lib/celerity/htmlunit/httpcore-4.2.2.jar +0 -0
  55. data/lib/celerity/htmlunit/httpmime-4.2.3.jar +0 -0
  56. data/lib/celerity/htmlunit/jetty-http-8.1.9.v20130131.jar +0 -0
  57. data/lib/celerity/htmlunit/jetty-io-8.1.9.v20130131.jar +0 -0
  58. data/lib/celerity/htmlunit/jetty-util-8.1.9.v20130131.jar +0 -0
  59. data/lib/celerity/htmlunit/jetty-websocket-8.1.9.v20130131.jar +0 -0
  60. data/lib/celerity/htmlunit/nekohtml-1.9.18.jar +0 -0
  61. data/lib/celerity/htmlunit/sac-1.3.jar +0 -0
  62. data/lib/celerity/htmlunit/serializer-2.7.1.jar +0 -0
  63. data/lib/celerity/htmlunit/xalan-2.7.1.jar +0 -0
  64. data/lib/celerity/htmlunit/xercesImpl-2.10.0.jar +0 -0
  65. data/lib/celerity/htmlunit/xml-apis-1.4.01.jar +0 -0
  66. data/lib/celerity/identifier.rb +28 -0
  67. data/lib/celerity/ignoring_web_connection.rb +15 -0
  68. data/lib/celerity/input_element.rb +25 -0
  69. data/lib/celerity/javascript_debugger.rb +32 -0
  70. data/lib/celerity/listener.rb +143 -0
  71. data/lib/celerity/resources/no_viewer.png +0 -0
  72. data/lib/celerity/short_inspect.rb +29 -0
  73. data/lib/celerity/util.rb +129 -0
  74. data/lib/celerity/version.rb +3 -0
  75. data/lib/celerity/viewer_connection.rb +89 -0
  76. data/lib/celerity/watir_compatibility.rb +70 -0
  77. data/lib/celerity/xpath_support.rb +50 -0
  78. data/spec/browser_authentication_spec.rb +16 -0
  79. data/spec/browser_spec.rb +439 -0
  80. data/spec/button_spec.rb +24 -0
  81. data/spec/clickable_element_spec.rb +39 -0
  82. data/spec/default_viewer_spec.rb +23 -0
  83. data/spec/element_spec.rb +77 -0
  84. data/spec/filefield_spec.rb +18 -0
  85. data/spec/htmlunit_spec.rb +63 -0
  86. data/spec/implementation.rb +7 -0
  87. data/spec/index_offset_spec.rb +24 -0
  88. data/spec/link_spec.rb +16 -0
  89. data/spec/listener_spec.rb +142 -0
  90. data/spec/spec_helper.rb +6 -0
  91. data/spec/table_spec.rb +41 -0
  92. data/spec/watir_compatibility_spec.rb +32 -0
  93. data/tasks/benchmark.rake +4 -0
  94. data/tasks/check.rake +24 -0
  95. data/tasks/clean.rake +3 -0
  96. data/tasks/fix.rake +25 -0
  97. data/tasks/jar.rake +55 -0
  98. data/tasks/rdoc.rake +4 -0
  99. data/tasks/snapshot.rake +25 -0
  100. data/tasks/spec.rake +27 -0
  101. data/tasks/website.rake +10 -0
  102. data/tasks/yard.rake +16 -0
  103. data/website/benchmarks.html +237 -0
  104. data/website/css/color.css +153 -0
  105. data/website/css/hacks.css +3 -0
  106. data/website/css/layout.css +179 -0
  107. data/website/css/screen.css +5 -0
  108. data/website/css/textmate.css +226 -0
  109. data/website/css/typography.css +72 -0
  110. data/website/gfx/body_bg.gif +0 -0
  111. data/website/gfx/button_bg.jpg +0 -0
  112. data/website/gfx/header_bg.jpg +0 -0
  113. data/website/gfx/header_left.jpg +0 -0
  114. data/website/gfx/header_right.jpg +0 -0
  115. data/website/gfx/nav_bg.jpg +0 -0
  116. data/website/index.html +125 -0
  117. data/website/yard/index.html +1 -0
  118. metadata +246 -0
@@ -0,0 +1,29 @@
1
+ module Celerity
2
+ module ShortInspect
3
+
4
+ def short_inspect(opts)
5
+ if excluded_ivars = opts[:exclude]
6
+ if is_ruby19
7
+ excluded_ivars.map! { |ivar| ivar.to_sym }
8
+ end
9
+ ivars = (instance_variables - excluded_ivars)
10
+ elsif included_ivars = opts[:include]
11
+ if is_ruby19
12
+ included_ivars.map! { |ivar| ivar.to_sym }
13
+ end
14
+ ivars = included_ivars
15
+ else
16
+ raise ArgumentError, "unknown arg: #{opts.inspect}"
17
+ end
18
+
19
+ ivars.map! { |ivar| "#{ivar}=#{instance_variable_get(ivar).inspect}" }
20
+ '#<%s:0x%s %s>' % [self.class.name, self.hash.to_s(16), ivars.join(" ")]
21
+ end
22
+
23
+ private
24
+ def is_ruby19
25
+ RUBY_VERSION >= "1.9"
26
+ end
27
+
28
+ end
29
+ end
@@ -0,0 +1,129 @@
1
+ module Celerity
2
+ module Util
3
+ module_function
4
+
5
+ HtmlUnit2CelerityElement = {
6
+ HtmlUnit::Html::HtmlAnchor => Celerity::Link,
7
+ HtmlUnit::Html::HtmlArea => Celerity::Area,
8
+ HtmlUnit::Html::HtmlButton => Celerity::Button,
9
+ HtmlUnit::Html::HtmlSubmitInput => Celerity::Button,
10
+ HtmlUnit::Html::HtmlResetInput => Celerity::Button,
11
+ HtmlUnit::Html::HtmlImageInput => Celerity::Button,
12
+ HtmlUnit::Html::HtmlButtonInput => Celerity::Button,
13
+ HtmlUnit::Html::HtmlCaption => Celerity::Button, # ?
14
+ HtmlUnit::Html::HtmlCheckBoxInput => Celerity::CheckBox,
15
+ HtmlUnit::Html::HtmlDefinitionDescription => Celerity::Dd,
16
+ HtmlUnit::Html::HtmlDefinitionList => Celerity::Dl,
17
+ HtmlUnit::Html::HtmlDefinitionTerm => Celerity::Dt,
18
+ HtmlUnit::Html::HtmlDeletedText => Celerity::Del,
19
+ HtmlUnit::Html::HtmlDivision => Celerity::Div,
20
+ HtmlUnit::Html::HtmlFileInput => Celerity::FileField,
21
+ HtmlUnit::Html::HtmlForm => Celerity::Form,
22
+ HtmlUnit::Html::HtmlFrame => Celerity::Frame,
23
+ HtmlUnit::Html::HtmlHeading1 => Celerity::H1,
24
+ HtmlUnit::Html::HtmlHeading2 => Celerity::H2,
25
+ HtmlUnit::Html::HtmlHeading3 => Celerity::H3,
26
+ HtmlUnit::Html::HtmlHeading4 => Celerity::H4,
27
+ HtmlUnit::Html::HtmlHeading5 => Celerity::H5,
28
+ HtmlUnit::Html::HtmlHeading6 => Celerity::H6,
29
+ HtmlUnit::Html::HtmlHiddenInput => Celerity::Hidden,
30
+ HtmlUnit::Html::HtmlImage => Celerity::Image,
31
+ HtmlUnit::Html::HtmlLabel => Celerity::Label,
32
+ HtmlUnit::Html::HtmlListItem => Celerity::Li,
33
+ HtmlUnit::Html::HtmlMap => Celerity::Map,
34
+ HtmlUnit::Html::HtmlOption => Celerity::Option,
35
+ HtmlUnit::Html::HtmlOrderedList => Celerity::Ol,
36
+ HtmlUnit::Html::HtmlParagraph => Celerity::P,
37
+ HtmlUnit::Html::HtmlPasswordInput => Celerity::TextField,
38
+ HtmlUnit::Html::HtmlPreformattedText => Celerity::Pre,
39
+ HtmlUnit::Html::HtmlRadioButtonInput => Celerity::Radio,
40
+ HtmlUnit::Html::HtmlSelect => Celerity::SelectList,
41
+ HtmlUnit::Html::HtmlSpan => Celerity::Span,
42
+ HtmlUnit::Html::HtmlTable => Celerity::Table,
43
+ HtmlUnit::Html::HtmlTableBody => Celerity::TableBody,
44
+ HtmlUnit::Html::HtmlTableCell => Celerity::TableCell,
45
+ HtmlUnit::Html::HtmlTableDataCell => Celerity::TableCell,
46
+ HtmlUnit::Html::HtmlTableFooter => Celerity::TableFooter,
47
+ HtmlUnit::Html::HtmlTableHeader => Celerity::TableHeader,
48
+ HtmlUnit::Html::HtmlTableRow => Celerity::TableRow,
49
+ HtmlUnit::Html::HtmlTextArea => Celerity::TextField,
50
+ HtmlUnit::Html::HtmlTextInput => Celerity::TextField,
51
+ HtmlUnit::Html::HtmlUnorderedList => Celerity::Ul,
52
+ HtmlUnit::Html::HtmlInsertedText => Celerity::Ins
53
+ }
54
+
55
+ def htmlunit2celerity(klass)
56
+ HtmlUnit2CelerityElement[klass]
57
+ end
58
+
59
+ #
60
+ # HtmlUnit will recognize most common file types, but custom ones can be added here.
61
+ # Used for FileField uploads.
62
+ #
63
+
64
+ ContentTypes = {
65
+ ".bmp" => "image/x-ms-bmp",
66
+ ".doc" => "application/msword",
67
+ ".odg" => "application/vnd.oasis.opendocument.graphics",
68
+ ".odp" => "application/vnd.oasis.opendocument.presentation",
69
+ ".ods" => "application/vnd.oasis.opendocument.spreadsheet",
70
+ ".odt" => "application/vnd.oasis.opendocument.text",
71
+ ".ppt" => "application/vnd.ms-powerpoint",
72
+ ".xls" => "application/vnd.ms-excel",
73
+ }
74
+
75
+ def content_type_for(path)
76
+ if ct = java.net.URLConnection.getFileNameMap.getContentTypeFor(path)
77
+ return ct
78
+ else
79
+ ContentTypes[File.extname(path).downcase]
80
+ end
81
+ end
82
+
83
+ def normalize_text(string)
84
+ string.gsub("\302\240", ' '). # non-breaking space 00A0
85
+ gsub(/\n|\t/, ''). # get rid of newlines/tabs
86
+ strip
87
+ end
88
+
89
+ def logger_for(package_string)
90
+ java.util.logging.Logger.getLogger(package_string)
91
+ end
92
+
93
+ # number of spaces that separate the property from the value in the create_string method
94
+ TO_S_SIZE = 14
95
+
96
+ def create_string(element)
97
+ ret = []
98
+
99
+ unless (tag = element.getTagName).empty?
100
+ ret << "tag:".ljust(TO_S_SIZE) + tag
101
+ end
102
+
103
+ element.getAttributes.each do |_, attribute|
104
+ ret << " #{attribute.getName}:".ljust(TO_S_SIZE + 2) + attribute.getValue.to_s
105
+ end
106
+
107
+ unless (text = element.asText).empty?
108
+ ret << " text:".ljust(TO_S_SIZE + 2) + element.asText
109
+ end
110
+
111
+ ret.join("\n")
112
+ end
113
+
114
+ #
115
+ # Used internally.
116
+ #
117
+ # @param [String] string The string to match against.
118
+ # @param [Regexp, String, #to_s] what The match we're looking for.
119
+ # @return [Fixnum, true, false, nil]
120
+ #
121
+ # @api private
122
+ #
123
+
124
+ def matches?(string, what)
125
+ Regexp === what ? string.strip =~ what : string == what.to_s
126
+ end
127
+
128
+ end
129
+ end
@@ -0,0 +1,3 @@
1
+ module Celerity
2
+ VERSION = "0.9.2"
3
+ end
@@ -0,0 +1,89 @@
1
+ module Celerity
2
+ class ViewerConnection
3
+
4
+ #
5
+ # Create a new connection to the given host/port
6
+ #
7
+
8
+ def self.create(host, port)
9
+ # if the connection fails, we won't spend time loading json
10
+ socket = TCPSocket.new(host, port)
11
+ require "json"
12
+ new(socket)
13
+ end
14
+
15
+ def initialize(socket)
16
+ @socket = socket
17
+ end
18
+
19
+ #
20
+ # Tells the viewer to render the given HTML, with the given URL as base url.
21
+ #
22
+
23
+ def render_html(html, url)
24
+ send_data('method' => 'page_changed', 'html' => html, 'url' => url)
25
+ end
26
+
27
+ #
28
+ # Tells the viewer to save a screenshot of the current page to the given path.
29
+ # May not be available on all viewers.
30
+ #
31
+
32
+ def save(path)
33
+ send_data('method' => 'save', 'path' => path)
34
+ end
35
+
36
+
37
+ #
38
+ # Tells the viewer to dump the render tree to the given path.
39
+ # Only available in the Qt viewer.
40
+ #
41
+
42
+ def save_render_tree(path)
43
+ send_data('method' => 'save_render_tree', 'path' => path)
44
+ end
45
+
46
+ #
47
+ # Get the currently rendered page as a Base64-encoded PNG image.
48
+ # Only available in the Qt viewer.
49
+ #
50
+
51
+ def image_data
52
+ send_data('method' => 'image_data')
53
+ data = read_data
54
+ data['image'] || data['error']
55
+ end
56
+
57
+ #
58
+ # Close the connection.
59
+ #
60
+
61
+ def close
62
+ @socket.close rescue nil
63
+ end
64
+
65
+ private
66
+
67
+ def send_data(msg)
68
+ json = msg.to_json
69
+ data = "Content-Length: #{json.size}\n\n#{json}"
70
+ @socket.write data
71
+ @socket.flush
72
+
73
+ nil
74
+ end
75
+
76
+ def read_data
77
+ buf = ''
78
+ until buf =~ /\n\n\z/ || @socket.eof? || @socket.closed?
79
+ buf << @socket.read(1).to_s
80
+ end
81
+
82
+ return if buf.empty?
83
+
84
+ length = buf[/Content-Length: (\d+)/, 1].to_i
85
+ JSON.parse @socket.read(length)
86
+ end
87
+
88
+ end
89
+ end
@@ -0,0 +1,70 @@
1
+ module Celerity
2
+ class Browser
3
+ class << self
4
+
5
+ # Added for Watir compatibility - not in use by Celerity
6
+ attr_accessor :speed, :attach_timeout, :visible
7
+ # Added for Watir compatibility - not in use by Celerity
8
+ alias_method :start_window, :start
9
+ # Added for Watir compatibility - not in use by Celerity
10
+ def each; end
11
+ end
12
+
13
+ # Added for Watir compatibility - not in use by Celerity
14
+ attr_accessor :visible
15
+
16
+ # Added for Watir compatibility - not in use by Celerity
17
+ def bring_to_front; true; end
18
+ # Added for Watir compatibility - not in use by Celerity
19
+ def speed=(s); s end
20
+ end
21
+
22
+
23
+ module ClickableElement
24
+ alias_method :click_no_wait, :click
25
+ end
26
+
27
+ module Container
28
+ alias_method :checkbox, :check_box
29
+ alias_method :checkBox, :check_box
30
+ alias_method :body, :tbody
31
+ alias_method :bodies, :tbodies
32
+ end
33
+
34
+ class Element
35
+ alias_method :exists, :exists?
36
+ alias_method :innerText, :text
37
+ alias_method :inner_text, :text
38
+ end
39
+
40
+ class Image
41
+ alias_method :hasLoaded?, :loaded?
42
+ alias_method :fileSize, :file_size
43
+ alias_method :fileCreatedDate, :file_created_date
44
+ end
45
+
46
+ class Link
47
+ alias_method :click_no_wait, :click
48
+ end
49
+
50
+ class RadioCheckCommon
51
+ alias_method :isSet?, :set?
52
+ alias_method :getState, :set?
53
+ end
54
+
55
+ class SelectList
56
+ alias_method :getSelectedItems, :selected_options
57
+ alias_method :getAllContents, :options
58
+ alias_method :clearSelection, :clear
59
+ alias_method :includes?, :include?
60
+ end
61
+
62
+ class TextField
63
+ alias_method :dragContentsTo, :drag_contents_to
64
+ alias_method :getContents, :value
65
+
66
+ def requires_typing; end
67
+ end
68
+ end
69
+
70
+ Celerity::IE = Celerity::Browser
@@ -0,0 +1,50 @@
1
+ module Celerity
2
+
3
+ #
4
+ # Module to search by xpath
5
+ #
6
+
7
+ module XpathSupport
8
+
9
+ #
10
+ # Get the first element found matching the given XPath.
11
+ #
12
+ # @param [String] xpath
13
+ # @return [Celerity::Element] An element subclass (or Element if none is found)
14
+ #
15
+
16
+ def element_by_xpath(xpath)
17
+ assert_exists
18
+ obj = @page.getFirstByXPath(xpath)
19
+ element_from_dom_node(obj, ":xpath and #{xpath.inspect}")
20
+ end
21
+
22
+ #
23
+ # Get all the elements matching the given XPath.
24
+ #
25
+ # @param [String] xpath
26
+ # @return [Array<Celerity::Element>] array of elements
27
+ #
28
+
29
+ def elements_by_xpath(xpath)
30
+ assert_exists
31
+ objects = @page.getByXPath(xpath)
32
+ # should use an ElementCollection here?
33
+ objects.map { |o| element_from_dom_node(o) }
34
+ end
35
+
36
+ #
37
+ # Convert the given HtmlUnit DomNode to a Celerity object
38
+ #
39
+
40
+ def element_from_dom_node(obj, identifier_string = nil)
41
+ element_class = Util.htmlunit2celerity(obj.class) || Element
42
+ element = element_class.new(self, :object, obj)
43
+
44
+ element.identifier_string = identifier_string
45
+ element.extend(ClickableElement) unless element.is_a?(ClickableElement)
46
+
47
+ element
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,16 @@
1
+ require File.expand_path("../watirspec/spec_helper", __FILE__)
2
+
3
+ describe "Browser" do
4
+
5
+ describe "#credentials=" do
6
+ it "sets the basic authentication credentials" do
7
+ browser.goto(WatirSpec.host + "/authentication")
8
+
9
+ browser.text.should_not include("ok")
10
+ browser.credentials = "foo:bar"
11
+
12
+ browser.goto(WatirSpec.host + "/authentication")
13
+ browser.text.should include("ok")
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,439 @@
1
+ # encoding: utf-8
2
+
3
+ require File.expand_path("../watirspec/spec_helper", __FILE__)
4
+
5
+ describe "Browser" do
6
+ describe "#new" do
7
+ it "raises TypeError if argument is not a Hash" do
8
+ lambda { Browser.new(:foo) }.should raise_error(TypeError)
9
+ end
10
+
11
+ it "raises ArgumentError if given bad arguments for :render key" do
12
+ lambda { Browser.new(:render => :foo) }.should raise_error(ArgumentError)
13
+ end
14
+
15
+ it "raises ArgumentError if given bad arguments for :browser key" do
16
+ lambda { Browser.new(:browser => 'foo') }.should raise_error(ArgumentError)
17
+ end
18
+
19
+ it "raises ArgumentError if given an unknown option" do
20
+ lambda { Browser.new(:foo => 1) }.should raise_error(ArgumentError)
21
+ end
22
+
23
+ it "should hold the init options" do
24
+ browser.options.should == WatirSpec.implementation.browser_args.first
25
+ end
26
+
27
+ it "should use the specified proxy" do
28
+ # TODO: find a better way to test this with rack
29
+ require 'webrick/httpproxy'
30
+
31
+ received = false
32
+ blk = lambda { received = true }
33
+ port = WatirSpec::Server.find_free_port_above(2001)
34
+
35
+ s = WEBrick::HTTPProxyServer.new(:Port => port,
36
+ :ProxyContentHandler => blk)
37
+ Thread.new { s.start }
38
+
39
+ opts = WatirSpec.implementation.browser_args.first.merge(:proxy => "localhost:#{port}")
40
+
41
+ begin
42
+ b = Browser.new(opts)
43
+ b.goto(WatirSpec.host)
44
+ ensure
45
+ s.shutdown
46
+ b.close if b
47
+ end
48
+
49
+ received.should be_true
50
+ end
51
+
52
+ it "should use the specified user agent" do
53
+ opts = WatirSpec.implementation.browser_args.first.merge(:user_agent => "Celerity")
54
+
55
+ b = Browser.new(opts)
56
+
57
+ begin
58
+ b.goto(WatirSpec.host + "/header_echo")
59
+ b.text.should include('"HTTP_USER_AGENT"=>"Celerity"')
60
+ ensure
61
+ b.close
62
+ end
63
+ end
64
+
65
+ it "does not try to find a viewer if created with :viewer => false" do
66
+ ViewerConnection.should_not_receive(:create)
67
+
68
+ Browser.new(:viewer => false).close
69
+ end
70
+
71
+ it "tries to find a viewer if created with :viewer => nil" do
72
+ ViewerConnection.should_receive(:create).with("127.0.0.1", 6429)
73
+
74
+ Browser.new(:viewer => nil).close
75
+ end
76
+
77
+ it "tries to find a viewer on the specified host/port with :viewer => String" do
78
+ ViewerConnection.should_receive(:create).with("localhost", 1234)
79
+
80
+ Browser.new(:viewer => "localhost:1234").close
81
+ end
82
+
83
+ it "should use the specified cache limit" do
84
+ opts = WatirSpec.implementation.browser_args.first.merge(:cache_limit => 100)
85
+ b = Browser.new(opts)
86
+
87
+ begin
88
+ b.cache_limit.should == 100
89
+ ensure
90
+ b.close
91
+ end
92
+ end
93
+
94
+ it "should use the Firefox 3 browser version when specified" do
95
+ Browser.new(:browser => :firefox).webclient.browser_version.nickname.should == "FF3"
96
+ Browser.new(:browser => :firefox3).webclient.browser_version.nickname.should == "FF3"
97
+ end
98
+
99
+ it "should use the Firefox 3.6 browser version when specified" do
100
+ Browser.new(:browser => :firefox_3_6).webclient.browser_version.nickname.should == "FF3.6"
101
+ Browser.new(:browser => :ff36).webclient.browser_version.nickname.should == "FF3.6"
102
+ end
103
+
104
+ it "should use the Internet Explorer 7 browser version when specified" do
105
+ Browser.new(:browser => :internet_explorer).webclient.browser_version.nickname.should == "IE7"
106
+ Browser.new(:browser => :internet_explorer7).webclient.browser_version.nickname.should == "IE7"
107
+ Browser.new(:browser => :internet_explorer_7).webclient.browser_version.nickname.should == "IE7"
108
+ Browser.new(:browser => :ie).webclient.browser_version.nickname.should == "IE7"
109
+ end
110
+
111
+ it "should use the Internet Explorer 8 browser version when specified" do
112
+ Browser.new(:browser => :internet_explorer_8).webclient.browser_version.nickname.should == "IE8"
113
+ Browser.new(:browser => :ie8).webclient.browser_version.nickname.should == "IE8"
114
+ end
115
+
116
+ it "should turn off CSS" do
117
+ b = Browser.new(:css => false)
118
+ b.css.should be_false
119
+ end
120
+
121
+ end
122
+
123
+ describe "#html" do
124
+ %w(shift_jis iso-2022-jp euc-jp).each do |charset|
125
+ it "returns decoded #{charset.upcase} when :charset specified" do
126
+ opts = WatirSpec.implementation.browser_args.first.merge(:charset => charset.upcase)
127
+ browser = Browser.new(opts)
128
+
129
+ begin
130
+ browser.goto(WatirSpec.files + "/#{charset}_text.html")
131
+ # Browser#text is automagically transcoded into the right charset, but Browser#html isn't.
132
+ browser.html.should =~ /本日は晴天なり。/
133
+ ensure
134
+ browser.close
135
+ end
136
+ end
137
+ end
138
+
139
+ it "does not fail for huge pages" do
140
+ browser.goto WatirSpec.host + "/big"
141
+ browser.html.should include("hello</body>")
142
+ end
143
+ end
144
+
145
+ describe "#text" do
146
+ it "does not fail for huge pages" do
147
+ browser.goto WatirSpec.host + "/big"
148
+ browser.text.should include("hello")
149
+ end
150
+ end
151
+
152
+ describe "#response_headers" do
153
+ it "returns the response headers (as a hash)" do
154
+ browser.goto(WatirSpec.host + "/non_control_elements.html")
155
+ browser.response_headers.should be_kind_of(Hash)
156
+ browser.response_headers['Date'].should be_kind_of(String)
157
+ browser.response_headers['Content-Type'].should be_kind_of(String)
158
+ end
159
+ end
160
+
161
+ describe "#content_type" do
162
+ it "returns the content type" do
163
+ browser.goto(WatirSpec.host + "/non_control_elements.html")
164
+ browser.content_type.should =~ /\w+\/\w+/
165
+ end
166
+ end
167
+
168
+ describe "#io" do
169
+ it "returns the io object of the content" do
170
+ browser.goto(WatirSpec.files + "/non_control_elements.html")
171
+ browser.io.should be_kind_of(IO)
172
+ browser.io.read.should == File.read("#{WatirSpec.html}/non_control_elements.html")
173
+ end
174
+ end
175
+
176
+ describe "#goto" do
177
+ it "raises UnexpectedPageException if the content type is not understood" do
178
+ lambda { browser.goto(WatirSpec.host + "/octet_stream") }.should raise_error(UnexpectedPageException)
179
+ end
180
+
181
+ it "takes a 2nd argument of headers" do
182
+ browser.goto(WatirSpec.host + "/header_echo", {'Accept-Language'=>'fr','Accept'=>'application/json'})
183
+ browser.text.should include('"HTTP_ACCEPT"=>"application/json"')
184
+ browser.text.should include('"HTTP_ACCEPT_LANGUAGE"=>"fr"')
185
+ end
186
+ end
187
+
188
+ describe "#cookies" do
189
+ it "returns set cookies as a Ruby hash" do
190
+ browser = WatirSpec.new_browser
191
+ begin
192
+ browser.cookies.should == {}
193
+
194
+ browser.goto(WatirSpec.host + "/set_cookie")
195
+
196
+ cookies = browser.cookies
197
+ cookies.size.should == 1
198
+ cookies[WatirSpec::Server.bind]['monster'].should == "/"
199
+ ensure
200
+ browser.close
201
+ end
202
+ end
203
+ end
204
+
205
+ describe "#clear_cookies" do
206
+ it "clears all cookies" do
207
+ b = WatirSpec.new_browser
208
+
209
+ begin
210
+ b.cookies.should be_empty
211
+
212
+ b.goto(WatirSpec.host + "/set_cookie")
213
+ b.cookies.size.should == 1
214
+ b.clear_cookies
215
+ b.cookies.should be_empty
216
+ ensure
217
+ b.close
218
+ end
219
+ end
220
+ end
221
+
222
+ describe "add_cookie" do
223
+ it "adds a cookie with the given domain, name and value" do
224
+ begin
225
+ browser.add_cookie("example.com", "foo", "bar")
226
+ cookies = browser.cookies
227
+ cookies.should be_instance_of(Hash)
228
+ cookies.should have_key('example.com')
229
+ cookies['example.com']['foo'].should == 'bar'
230
+ ensure
231
+ browser.clear_cookies
232
+ end
233
+ end
234
+
235
+ it "adds a cookie with the specified options" do
236
+ begin
237
+ browser.add_cookie("example.com", "foo", "bar", :path => "/foobar", :expires => Time.now + 100000)
238
+ cookies = browser.cookies
239
+ cookies.should be_instance_of(Hash)
240
+ cookies['example.com']['foo'].should == 'bar'
241
+ ensure
242
+ browser.clear_cookies
243
+ end
244
+ end
245
+ end
246
+
247
+ describe "remove_cookie" do
248
+ it "removes the cookie for the given domain and name" do
249
+ b = WatirSpec.new_browser
250
+ begin
251
+ b.goto(WatirSpec.host + "/set_cookie")
252
+
253
+ b.remove_cookie(WatirSpec::Server.bind, "monster")
254
+ b.cookies.should be_empty
255
+ ensure
256
+ b.close
257
+ end
258
+ end
259
+
260
+ it "raises an error if no such cookie exists" do
261
+ lambda { browser.remove_cookie("bogus.com", "bar") }.should raise_error(CookieNotFoundError)
262
+ end
263
+ end
264
+
265
+ describe "#wait" do
266
+ it "should wait for javascript timers to finish" do
267
+ alerts = 0
268
+ browser.add_listener(:alert) { alerts += 1 }
269
+ browser.goto(WatirSpec.files + "/timeout.html")
270
+ browser.div(:id, 'alert').click
271
+ browser.wait.should be_true
272
+ alerts.should == 1
273
+ end
274
+
275
+ it "should pass the correct args to webclient" do
276
+ browser.webclient.should_receive(:waitForBackgroundJavaScript).with(10000)
277
+ browser.wait
278
+
279
+ browser.webclient.should_receive(:waitForBackgroundJavaScript).with(3000)
280
+ browser.wait(3)
281
+ end
282
+
283
+ end
284
+
285
+ describe "#wait_while" do
286
+ it "waits until the specified condition becomes false" do
287
+ browser.goto(WatirSpec.files + "/timeout.html")
288
+ browser.div(:id, "change").click
289
+ browser.wait_while { browser.contains_text("Trigger change") }
290
+ browser.wait_until {
291
+ browser.div(:id, "change").text == "all done"
292
+ }
293
+ end
294
+
295
+ it "returns the value returned from the block" do
296
+ browser.wait_while { false }.should == false
297
+ end
298
+ end
299
+
300
+ describe "#wait_until" do
301
+ it "waits until the condition becomes true" do
302
+ browser.goto(WatirSpec.files + "/timeout.html")
303
+ browser.div(:id, "change").click
304
+ browser.wait_until { browser.contains_text("all done") }
305
+ end
306
+
307
+ it "returns the value returned from the block" do
308
+ browser.wait_until { true }.should == true
309
+ end
310
+ end
311
+
312
+ describe "#element_by_xpath" do
313
+ it "returns usable elements even though they're not supported" do
314
+ browser.goto(WatirSpec.files + "/forms_with_input_elements.html")
315
+
316
+ el = browser.element_by_xpath("//link")
317
+ el.should be_instance_of(Celerity::Element)
318
+ el.should be_kind_of(Celerity::ClickableElement)
319
+ el.rel.should == "stylesheet"
320
+ end
321
+
322
+ it "includes the xpath in an exception message" do
323
+ browser.goto(WatirSpec.files + "/forms_with_input_elements.html")
324
+
325
+ the_xpath = "//div[contains(@class, 'this does not exist')]"
326
+ el = browser.element_by_xpath(the_xpath)
327
+
328
+ lambda { el.visible? }.should raise_error(
329
+ Celerity::Exception::UnknownObjectException, Regexp.new(Regexp.escape(the_xpath)))
330
+ end
331
+ end
332
+
333
+ describe "#focused_element" do
334
+ it "returns the element that currently has the focus" do
335
+ b = WatirSpec.new_browser
336
+ b.goto(WatirSpec.files + "/forms_with_input_elements.html")
337
+ b.focused_element.id.should == "new_user_first_name"
338
+
339
+ b.close
340
+ end
341
+ end
342
+
343
+ describe "#status_code" do
344
+ it "returns the status code of the last request" do
345
+ browser.goto(WatirSpec.files + "/forms_with_input_elements.html")
346
+ browser.status_code.should == 200
347
+
348
+ browser.goto(WatirSpec.host + "/doesnt_exist")
349
+ browser.status_code.should == 404
350
+ end
351
+ end
352
+
353
+ describe "#status_code_exceptions" do
354
+ it "raises status code exceptions if set to true" do
355
+ browser.status_code_exceptions = true
356
+
357
+ begin
358
+ lambda {
359
+ browser.goto(WatirSpec.host + "/doesnt_exist")
360
+ }.should raise_error(NavigationException)
361
+ ensure
362
+ browser.status_code_exceptions = false
363
+ end
364
+ end
365
+ end
366
+
367
+ describe "#javascript_exceptions" do
368
+ it "raises javascript exceptions if set to true" do
369
+ browser.goto(WatirSpec.files + "/forms_with_input_elements.html")
370
+ browser.javascript_exceptions = true
371
+ begin
372
+ lambda { browser.execute_script("no_such_function()") }.should raise_error
373
+ ensure
374
+ browser.javascript_exceptions = false
375
+ end
376
+ end
377
+ end
378
+
379
+ describe "#add_listener" do
380
+ it "should click OK for confirm() calls" do
381
+ browser.goto(WatirSpec.files + "/forms_with_input_elements.html")
382
+ browser.add_listener(:confirm) { }
383
+ browser.execute_script("confirm()").should == true
384
+ end
385
+ end
386
+
387
+ describe "#remove_listener" do
388
+ it "should remove the given listener Proc" do
389
+ browser.goto(WatirSpec.files + "/forms_with_input_elements.html")
390
+
391
+ called = false
392
+ listener = lambda { called = true }
393
+
394
+ browser.add_listener(:alert, &listener)
395
+ browser.execute_script("alert('foo')")
396
+ called.should be_true
397
+
398
+ called = false
399
+ browser.remove_listener(:alert, listener)
400
+ browser.execute_script("alert('foo')")
401
+ called.should be_false
402
+ end
403
+ end
404
+
405
+ describe "#add_checker" do
406
+
407
+ # watir only supports a lambda instance as argument, celerity supports both
408
+ it "runs the given block on each page load" do
409
+ output = ''
410
+
411
+ browser.add_checker { |browser| output << browser.text }
412
+ browser.goto(WatirSpec.files + "/non_control_elements.html")
413
+
414
+ output.should include('Dubito, ergo cogito, ergo sum')
415
+ end
416
+ end
417
+
418
+
419
+ describe "#confirm" do
420
+ it "clicks 'OK' for a confirm() call" do
421
+ browser.goto(WatirSpec.files + "/forms_with_input_elements.html")
422
+
423
+ browser.confirm(true) do
424
+ browser.execute_script('confirm()').should be_true
425
+ end
426
+ end
427
+
428
+ it "clicks 'cancel' for a confirm() call" do
429
+ browser.goto(WatirSpec.files + "/forms_with_input_elements.html")
430
+
431
+ browser.confirm(false) do
432
+ browser.execute_script('confirm()').should be_false
433
+ end
434
+ end
435
+ end
436
+
437
+
438
+
439
+ end