watir-webdriver 0.0.1.dev3 → 0.0.1.dev4

Sign up to get free protection for your applications and to get access to all the features.
@@ -3,6 +3,10 @@
3
3
  Watir implementation built on WebDriver's Ruby bindings.
4
4
  See http://rubyforge.org/pipermail/wtr-development/2009-October/001313.html.
5
5
 
6
+ = API docs
7
+
8
+ http://jarib.github.com/watir-webdriver/doc/
9
+
6
10
  = Description
7
11
 
8
12
  The file in lib/watir/elements/generated.rb is autogenerated from the HTML5 spec. This is done by extracting the IDL parts from the spec and processing them with the WebIDL gem (link below).
@@ -29,4 +33,4 @@ The file in lib/watir/elements/generated.rb is autogenerated from the HTML5 spec
29
33
 
30
34
  == Copyright
31
35
 
32
- Copyright (c) 2009 Jari Bakken. See LICENSE for details.
36
+ Copyright (c) 2009-2010 Jari Bakken. See LICENSE for details.
data/Rakefile CHANGED
@@ -97,10 +97,10 @@ task :default => :spec
97
97
 
98
98
  begin
99
99
  require 'yard'
100
- require 'support/yard/handlers/attributes_handler'
100
+ require 'support/yard_handlers'
101
101
  YARD::Rake::YardocTask.new
102
102
  rescue LoadError
103
- task :yardoc do
103
+ task :yard do
104
104
  abort "YARD is not available. In order to run yardoc, you must: sudo gem install yard"
105
105
  end
106
106
  end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.1.dev3
1
+ 0.0.1.dev4
@@ -295,6 +295,10 @@ module Watir
295
295
  end
296
296
  end
297
297
 
298
+ def browser
299
+ @parent.browser
300
+ end
301
+
298
302
  private
299
303
 
300
304
  def selector_string
@@ -15,6 +15,13 @@ module Watir
15
15
  end
16
16
  end
17
17
 
18
+ #
19
+ # Create a Watir::Browser instance
20
+ #
21
+ # @param [:firefox, :ie, :chrome, :remote] browser
22
+ # @param args Passed to the underlying driver
23
+ #
24
+
18
25
  def initialize(browser, *args)
19
26
  case browser
20
27
  when Symbol, String
@@ -32,8 +39,15 @@ module Watir
32
39
  '#<%s:0x%x url=%s title=%s>' % [self.class, hash*2, url.inspect, title.inspect]
33
40
  end
34
41
 
42
+ #
43
+ # Goto the given URL
44
+ #
45
+ # @param [String] uri The url.
46
+ # @return [String] The url you end up at.
47
+ #
48
+
35
49
  def goto(uri)
36
- uri = "http://#{uri}" unless uri.include?("://")
50
+ uri = "http://#{uri}" unless uri.include?("://") || uri =~ /^\w+:/
37
51
 
38
52
  @driver.navigate.to uri
39
53
  run_checkers
@@ -82,10 +96,6 @@ module Watir
82
96
  @driver.navigate.refresh
83
97
  end
84
98
 
85
- def exist?
86
- true
87
- end
88
-
89
99
  def status
90
100
  execute_script "return window.status;"
91
101
  end
@@ -119,6 +129,8 @@ module Watir
119
129
  @error_checkers.each { |e| e[self] }
120
130
  end
121
131
 
132
+ #
133
+ # Protocol shared with BaseElement
122
134
  #
123
135
  # @api private
124
136
  #
@@ -127,5 +139,13 @@ module Watir
127
139
  true # TODO: assert browser is open
128
140
  end
129
141
 
142
+ def exist?
143
+ true
144
+ end
145
+
146
+ def browser
147
+ self
148
+ end
149
+
130
150
  end # Browser
131
151
  end # Watir
@@ -1,10 +1,10 @@
1
1
  // stolen from injectableSelenium.js in WebDriver
2
-
3
2
  var browserbot = {
4
3
 
5
- triggerEvent : function(element, eventType, canBubble, controlKeyDown, altKeyDown, shiftKeyDown, metaKeyDown) {
6
- canBubble = (typeof(canBubble) == undefined) ? true : canBubble;
7
- if (element.fireEvent && element.ownerDocument && element.ownerDocument.createEventObject) { // IE
4
+ triggerEvent: function(element, eventType, canBubble, controlKeyDown, altKeyDown, shiftKeyDown, metaKeyDown) {
5
+ canBubble = (typeof(canBubble) == undefined) ? true: canBubble;
6
+ if (element.fireEvent && element.ownerDocument && element.ownerDocument.createEventObject) {
7
+ // IE
8
8
  var evt = this.createEventObject(element, controlKeyDown, altKeyDown, shiftKeyDown, metaKeyDown);
9
9
  element.fireEvent('on' + eventType, evt);
10
10
  } else {
@@ -15,16 +15,16 @@ var browserbot = {
15
15
  evt.metaKey = metaKeyDown;
16
16
  evt.altKey = altKeyDown;
17
17
  evt.ctrlKey = controlKeyDown;
18
- } catch (e) {
18
+ } catch(e) {
19
19
  // Nothing sane to do
20
- }
20
+ }
21
21
 
22
22
  evt.initEvent(eventType, canBubble, true);
23
23
  element.dispatchEvent(evt);
24
24
  }
25
25
  },
26
26
 
27
- getVisibleText : function() {
27
+ getVisibleText: function() {
28
28
  var selection = getSelection();
29
29
  var range = document.createRange();
30
30
  range.selectNodeContents(document.documentElement);
@@ -32,14 +32,14 @@ var browserbot = {
32
32
  return selection.toString();
33
33
  },
34
34
 
35
- getOuterHTML : function(element) {
36
- if(element.outerHTML) {
35
+ getOuterHTML: function(element) {
36
+ if (element.outerHTML) {
37
37
  return element.outerHTML;
38
- } else if (typeof(XMLSerializer) != undefined) {
39
- return new XMLSerializer().serializeToString(element);
40
- } else {
41
- throw "can't get outerHTML in this browser";
42
- }
38
+ } else if (typeof(XMLSerializer) != undefined) {
39
+ return new XMLSerializer().serializeToString(element);
40
+ } else {
41
+ throw "can't get outerHTML in this browser";
42
+ }
43
43
  }
44
44
 
45
45
 
@@ -1,6 +1,8 @@
1
1
  module Watir
2
2
  class ButtonsCollection < ElementCollection
3
3
 
4
+ private
5
+
4
6
  def elements
5
7
  @elements ||= ButtonLocator.new(
6
8
  @parent.wd,
@@ -12,7 +12,7 @@ module Watir
12
12
  end
13
13
 
14
14
  def length
15
- to_a.length
15
+ elements.length
16
16
  end
17
17
  alias_method :size, :length
18
18
 
@@ -20,19 +20,39 @@ module Watir
20
20
  to_a[idx] || @element_class.new(@parent, :index, idx)
21
21
  end
22
22
 
23
+ #
24
+ # First element of this collection
25
+ #
26
+ # @return Watir::BaseElement
27
+ #
28
+
23
29
  def first
24
30
  to_a[0] || @element_class.new(@parent, :index, 0)
25
31
  end
26
32
 
33
+ #
34
+ # Last element of the collection
35
+ #
36
+ # @return Watir::BaseElement
37
+ #
38
+
27
39
  def last
28
40
  to_a[-1] || @element_class.new(@parent, :index, -1)
29
41
  end
30
42
 
43
+ #
44
+ # This collection as an Array
45
+ #
46
+ # @return [Array<Watir::BaseElement>]
47
+ #
48
+
31
49
  def to_a
32
50
  # TODO: optimize - lazily @element_class instance
33
51
  @to_a ||= elements.map { |e| @element_class.new(@parent, :element, e) }
34
52
  end
35
53
 
54
+ private
55
+
36
56
  def elements
37
57
  @elements ||= ElementLocator.new(
38
58
  @parent.wd,
@@ -1,6 +1,8 @@
1
1
  module Watir
2
2
  class TrsCollection < ElementCollection
3
3
 
4
+ private
5
+
4
6
  def elements
5
7
  return super unless @parent.kind_of?(Watir::Table)
6
8
  @elements ||= TableRowLocator.new(
@@ -1,6 +1,8 @@
1
1
  module Watir
2
2
  class TextFieldsCollection < ElementCollection
3
3
 
4
+ private
5
+
4
6
  def elements
5
7
  @elements ||= TextFieldLocator.new(
6
8
  @parent.wd,
@@ -2,6 +2,11 @@
2
2
  module Watir
3
3
  module Container
4
4
  class << self
5
+
6
+ #
7
+ # @api private
8
+ #
9
+
5
10
  def add(method, &blk)
6
11
  define_method(method, &blk)
7
12
  end
@@ -52,15 +52,15 @@ module Watir
52
52
  attributes(:html_collection => ([:options]))
53
53
  end
54
54
 
55
- class Object < HTMLElement
56
- identifier(:tag_name => "object")
57
-
58
- container_method(:object)
59
-
60
- collection_method(:objects)
61
-
62
- attributes(:string => ([:data, :type, :name, :use_map, :width, :height, :content_window, :validity, :validation_message]), :document => ([:content_document]), :html_element => ([:form]), :bool => ([:will_validate]))
63
- end
55
+ # class Object < HTMLElement
56
+ # identifier(:tag_name => "object")
57
+ #
58
+ # container_method(:object)
59
+ #
60
+ # collection_method(:objects)
61
+ #
62
+ # attributes(:string => ([:data, :type, :name, :use_map, :width, :height, :content_window, :validity, :validation_message]), :document => ([:content_document]), :html_element => ([:form]), :bool => ([:will_validate]))
63
+ # end
64
64
 
65
65
  class DList < HTMLElement
66
66
  identifier(:tag_name => "dl")
@@ -12,7 +12,9 @@ module Watir
12
12
 
13
13
  def clear
14
14
  assert_exists
15
- raise "you can only clear multi-selects" unless multiple?
15
+
16
+ raise Error, "you can only clear multi-selects" unless multiple?
17
+
16
18
  options.each do |o|
17
19
  o.toggle if o.selected?
18
20
  end
@@ -24,17 +26,16 @@ module Watir
24
26
  end
25
27
 
26
28
  def select(str_or_rx)
27
- select_by :text, str_or_rx
29
+ select_by :text, str_or_rx, multiple?
28
30
  end
29
31
 
30
- # TODO: deprecate?
31
32
  def select_value(str_or_rx)
32
- select_by :value, str_or_rx
33
+ select_by :value, str_or_rx, multiple?
33
34
  end
34
35
 
35
36
  def selected?(str_or_rx)
36
37
  assert_exists
37
- matches = options.select { |e| str_or_rx === e.text }
38
+ matches = @element.find_elements(:tag_name, 'option').select { |e| str_or_rx === e.text || str_or_rx === e.attribute(:label) }
38
39
 
39
40
  if matches.empty?
40
41
  raise UnknownObjectException, "Unable to locate option matching #{str_or_rx.inspect}"
@@ -57,17 +58,90 @@ module Watir
57
58
 
58
59
  private
59
60
 
60
- def select_by(how, str_or_rx)
61
- assert_exists
62
- os = options.select { |e| str_or_rx === e.send(how) }
61
+ def select_by(how, str_or_rx, multiple)
62
+ case str_or_rx
63
+ when String
64
+ select_by_string(how, str_or_rx, multiple)
65
+ when Regexp
66
+ select_by_regexp(how, str_or_rx, multiple)
67
+ else
68
+ raise ArgumentError, "expected String or Regexp, got #{str_or_rx.inspect}:#{str_or_rx.class}"
69
+ end
70
+ end
71
+
72
+ def select_by_string(how, string, multiple)
73
+ xpath = option_xpath_for(how, string)
74
+ if multiple
75
+ elements = @element.find_elements(:xpath, xpath)
76
+
77
+ if elements.empty?
78
+ raise NoValueFoundException, "#{string.inspect} not found in select list"
79
+ end
80
+
81
+ elements.each { |e| e.select unless e.selected? }
82
+ elements.first.text
83
+ else
84
+ begin
85
+ e = @element.find_element(:xpath, xpath)
86
+ rescue WebDriver::Error::WebDriverError # should be more specific
87
+ raise NoValueFoundException, "#{string.inspect} not found in select list"
88
+ end
89
+
90
+ e.select unless e.selected?
91
+ e.text
92
+ end
93
+ end
63
94
 
64
- if os.empty?
65
- raise NoValueFoundException, "#{str_or_rx.inspect} not found in select list"
95
+ def select_by_regexp(how, exp, multiple)
96
+ elements = @element.find_elements(:tag_name, 'option')
97
+ if elements.empty?
98
+ raise NoValueFoundException, "no options in select list"
66
99
  end
67
100
 
68
- os.each { |e| e.select unless e.selected? }
69
- os.first.text
101
+ if multiple
102
+ found = elements.select do |e|
103
+ next unless matches_regexp?(how, e, exp)
104
+ e.select unless e.selected?
105
+ true
106
+ end
107
+
108
+ if found.empty?
109
+ raise NoValueFoundException, "#{exp.inspect} not found in select list"
110
+ end
111
+
112
+ found.first.text
113
+ else
114
+ element = elements.find { |e| matches_regexp?(how, e, exp) }
115
+ unless element
116
+ raise NoValueFoundException, "#{exp.inspect} not found in select list"
117
+ end
118
+
119
+ element.select unless element.selected?
120
+ element.text
121
+ end
122
+ end
123
+
124
+ def option_xpath_for(how, string)
125
+ case how
126
+ when :text
127
+ "//option[normalize-space()=#{string.inspect} or @label=#{string.inspect}]"
128
+ when :value
129
+ "//option[@value=#{string.inspect}]"
130
+ else
131
+ raise Error, "unknown how: #{how.inspect}"
132
+ end
133
+ end
134
+
135
+ def matches_regexp?(how, element, exp)
136
+ case how
137
+ when :text
138
+ element.text =~ exp || element.attribute(:label) =~ exp
139
+ when :value
140
+ element.attribute(:value) =~ exp
141
+ else
142
+ raise Error, "unknown how: #{how.inspect}"
143
+ end
70
144
  end
71
145
 
72
- end
73
- end
146
+ end # SelectList
147
+ end # Watir
@@ -2,7 +2,6 @@
2
2
  module Watir
3
3
  class TextField < Input
4
4
 
5
- # perhaps we'll need a custom locate(), since this should also cover textareas
6
5
  attributes Watir::TextArea.typed_attributes
7
6
  def type; super; end # hacky, but we want Input#type here, which was overriden by TextArea's attributes
8
7
 
@@ -0,0 +1,87 @@
1
+ # require "ruby-debug"
2
+ require "#{File.dirname(__FILE__)}/../lib/watir-webdriver/core_ext/string"
3
+
4
+ module YARD
5
+ module Watir
6
+ class AttributesHandler < YARD::Handlers::Ruby::Base
7
+ handles method_call(:attributes)
8
+
9
+ TYPES = {
10
+ :string => "String",
11
+ :bool => "Boolean",
12
+ :int => "Integer"
13
+ }
14
+
15
+ def process
16
+ attributes = try_eval
17
+
18
+ if attributes.nil?
19
+ p :ignoring => statement.source, :in => namespace.to_s
20
+ return
21
+ end
22
+
23
+ TYPES.each do |type, return_type|
24
+ if attributes.member? type
25
+ create_attributes attributes[type], return_type
26
+ end
27
+ end
28
+ end
29
+
30
+ private
31
+
32
+ def create_attributes(names, return_type)
33
+ names.each do |attribute_name|
34
+ p :adding => "#{namespace}##{attribute_name}"
35
+ attribute_name = "#{attribute_name}?".to_sym if return_type == "Boolean"
36
+ register MethodObject.new(namespace, attribute_name, scope) do |o|
37
+ o.visibility = :public
38
+ o.explicit = false
39
+ o.docstring.add_tag YARD::Tags::Tag.new(:return, "", return_type)
40
+ end
41
+ end
42
+ end
43
+
44
+ def try_eval
45
+ eval "{#{statement.parameters.source}}"
46
+ rescue SyntaxError, StandardError
47
+ nil
48
+ end
49
+
50
+ end # AttributesHandler
51
+
52
+ class ContainerMethodHandler < YARD::Handlers::Ruby::Base
53
+ handles method_call(:container_method)
54
+
55
+ def process
56
+ name = statement.parameters.flatten.first
57
+ return_type = namespace.to_s
58
+ p :adding => "Watir::Container##{name}"
59
+
60
+ register MethodObject.new(P("Watir::Container"), name, :instance) do |o|
61
+ o.docstring.add_tag(YARD::Tags::Tag.new(:return, "", return_type))
62
+ end
63
+ end
64
+ end # ContainerMethodHandler
65
+
66
+ class CollectionMethodHandler < YARD::Handlers::Ruby::Base
67
+ handles method_call(:collection_method)
68
+
69
+ def process
70
+ name = statement.parameters.flatten.first
71
+ p :adding => "Watir::Container##{name}"
72
+
73
+ class_name = "#{name.to_s.camel_case}Collection"
74
+ return_type = "Watir::#{class_name}"
75
+
76
+ register MethodObject.new(P("Watir::Container"), name, :instance) do |o|
77
+ o.docstring.add_tag(YARD::Tags::Tag.new(:return, "", return_type))
78
+ end
79
+
80
+ register ClassObject.new(P("Watir"), class_name) do |o|
81
+ o.superclass = "Watir::ElementCollection"
82
+ end
83
+ end
84
+ end # CollectionMethodHandler
85
+
86
+ end # Watir
87
+ end # YARD
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: watir-webdriver
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1.dev3
4
+ version: 0.0.1.dev4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jari Bakken
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-01-21 00:00:00 +01:00
12
+ date: 2010-01-27 00:00:00 +01:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -102,13 +102,12 @@ files:
102
102
  - lib/watir-webdriver/locators/table_row_locator.rb
103
103
  - lib/watir-webdriver/locators/text_field_locator.rb
104
104
  - lib/watir-webdriver/xpath_support.rb
105
- - spec/element_locator_spec.rb
106
105
  - spec/spec_helper.rb
107
- - spec/xpath_builder_spec.rb
108
106
  - support/html5/html5.idl
109
107
  - support/html5/html5_extras.idl
110
108
  - support/html5/idl_extractor.rb
111
109
  - support/html5/watir_visitor.rb
110
+ - support/yard_handlers.rb
112
111
  has_rdoc: true
113
112
  homepage: http://github.com/jarib/watir-webdriver
114
113
  licenses: []
@@ -138,7 +137,6 @@ signing_key:
138
137
  specification_version: 3
139
138
  summary: Watir on WebDriver
140
139
  test_files:
141
- - spec/element_locator_spec.rb
142
140
  - spec/spec_helper.rb
143
141
  - spec/watirspec/area_spec.rb
144
142
  - spec/watirspec/areas_spec.rb
@@ -216,4 +214,3 @@ test_files:
216
214
  - spec/watirspec/text_fields_spec.rb
217
215
  - spec/watirspec/ul_spec.rb
218
216
  - spec/watirspec/uls_spec.rb
219
- - spec/xpath_builder_spec.rb
@@ -1,11 +0,0 @@
1
- # encoding: utf-8
2
- require "#{File.dirname(__FILE__)}/spec_helper"
3
-
4
- describe Watir::ElementLocator do
5
- def setup(selector)
6
- driver = mock("Driver")
7
- locator = Watir::ElementLocator.new(driver, selector)
8
-
9
- [driver, locator]
10
- end
11
- end
@@ -1,49 +0,0 @@
1
- # encoding: utf-8
2
- require "#{File.dirname(__FILE__)}/spec_helper"
3
-
4
- # describe Watir::XPathBuilder do
5
- # def build(selector)
6
- # XPathBuilder.build_from(selector)
7
- # end
8
- #
9
- # it "builds an xpath from a tag name and a single attribute" do
10
- # build(
11
- # :tag_name => "div",
12
- # :id => "foo"
13
- # ).should == '//div[@id="foo"]'
14
- # end
15
- #
16
- # it "builds an xpath from a tag name and multiple attributes" do
17
- # build(
18
- # :tag_name => "input",
19
- # :type => "radio",
20
- # :value => '1'
21
- # ).should == '//input[@type="radio" and @value="1"]'
22
- # end
23
- #
24
- # it "builds an xpath from a tag name, an attribute and an index" do
25
- # build(
26
- # :tag_name => "input",
27
- # :type => "text",
28
- # :index => 2
29
- # ).should == '//input[@type="text"][3]'
30
- # end
31
- #
32
- # it "builds an xpath from a single attribute" do
33
- # build(
34
- # :class => 'foo'
35
- # ).should == '//*[@class="foo"]'
36
- # end
37
- #
38
- # it "builds an xpath from a tag name and index" do
39
- # build(
40
- # :tag_name => 'span',
41
- # :index => 3
42
- # ).should == '//span[4]'
43
- # end
44
- #
45
- # it "returns nil if any the selector contains a regexp" do
46
- # build(:tag_name => /span|div/).should be_nil
47
- # end
48
-
49
- # end