watigiri 0.1.0 → 0.2.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 88ad103bcf8deb0b774e803ba687e340e8ee5373
4
- data.tar.gz: 3b29a90e092b817df788048b3f03a5acb2542848
3
+ metadata.gz: c30b44d2a541b53088b5a62f077bef279297c1bc
4
+ data.tar.gz: 9efb3cae6a9fc60c035ebedb6dd1c16cd58c24ac
5
5
  SHA512:
6
- metadata.gz: 621425770d2df585d453c8aaa1874d81c21e003ed580ab9861118cc48f04a7e66c6ef4474a070cdb1af9753468d6e0772990e067fac3b7d6b03ba8037339b0db
7
- data.tar.gz: 507d3b8fd60b950ee55a635e8adc7f2a3fd709bd94c6539ba0287c3677a187578115786104dfadee604f2ef0e963dc0380f499d64cbdda43a6a5e2fcdccc3fe6
6
+ metadata.gz: 84e1abf4aafa91e653fd3644997df5e43be6c3c245baf6be68b6ec723b0fb63955b2fd5a2e295b636c82862c54337d562ae41efd9d8914fcd1580b8d7cf3afe4
7
+ data.tar.gz: d418e2daaf3c1a64e1d82d8d434a77edde1b99c254b4b1081819616f3e87011fa0dba8ce8a71417287b86c63dd4b12e62bb62697fd72a00c7b553911cdb65009
@@ -2,4 +2,7 @@ sudo: false
2
2
  language: ruby
3
3
  rvm:
4
4
  - 2.4.1
5
- before_install: gem install bundler -v 1.15.3
5
+ before_install:
6
+ - export DISPLAY=:99
7
+ - sh -e /etc/init.d/xvfb start
8
+ - export PATH=~/.webdrivers:$PATH
data/Rakefile CHANGED
@@ -3,4 +3,7 @@ require "rspec/core/rake_task"
3
3
 
4
4
  RSpec::Core::RakeTask.new(:spec)
5
5
 
6
- task :default => :spec
6
+ require 'watirspec/rake_tasks'
7
+ WatirSpec::RakeTasks.new
8
+
9
+ task default: %i[spec watirspec:run]
@@ -9,8 +9,8 @@ module Watir
9
9
 
10
10
  def doc=(html)
11
11
  @doc = html
12
+ return if html.nil?
12
13
 
13
- return if @doc.nil?
14
14
  reset_doc = ->(browser) { browser.doc = nil }
15
15
  after_hooks.add(reset_doc)
16
16
  end
@@ -15,9 +15,10 @@ module Watir
15
15
 
16
16
  private
17
17
 
18
+ alias_method :watir_switch!, :switch!
18
19
  def switch!
19
20
  @browser.doc = nil
20
- super
21
+ watir_switch!
21
22
  end
22
23
 
23
24
  end # FramedDriver
@@ -7,6 +7,11 @@ require 'extensions/watir/iframe'
7
7
 
8
8
  require 'watigiri/locators/element/locator'
9
9
  require 'watigiri/locators/element/selector_builder'
10
- require 'watigiri/locators/element/validator'
11
10
 
12
11
  Watir.locator_namespace = Watigiri::Locators
12
+
13
+ # Use Watir Validator behaviors for all Elements
14
+ Watigiri::Locators::Element::Validator = Watir::Locators::Element::Validator
15
+ Watigiri::Locators::Button::Validator = Watir::Locators::Button::Validator
16
+ Watigiri::Locators::TextField::Validator = Watir::Locators::TextField::Validator
17
+
@@ -1,128 +1,189 @@
1
1
  module Watigiri
2
+ class Element
3
+ attr_reader :element, :selector
4
+
5
+ def initialize(element:, selector:)
6
+ @element = element
7
+ @selector = selector
8
+ end
9
+ end
10
+
2
11
  module Locators
3
- class Element
4
- class Locator < Watir::Locators::Element::Locator
12
+ module LocatorHelpers
13
+ def locate
14
+ @nokogiri = @selector.delete(:nokogiri)
15
+ @regex = regex?
5
16
 
6
- def locate
7
- @nokogiri = @selector.delete(:nokogiri)
17
+ return super unless @nokogiri || @regex
18
+ @query_scope.browser.doc ||= Nokogiri::HTML(@query_scope.html).tap { |d| d.css('script').remove }
19
+
20
+ element = find_first_by_multiple
21
+ return if element.nil?
22
+ @nokogiri ? element.element : nokogiri_to_selenium(element)
23
+ end
8
24
 
9
- return super unless @nokogiri
10
- @query_scope.browser.doc ||= Nokogiri::HTML(@query_scope.html).tap {|d| d.css('script').remove }
25
+ def locate_all
26
+ @nokogiri = @selector.delete(:nokogiri)
27
+ @regex = regex?
11
28
 
12
- reset_doc = ->(browser) { browser.doc = nil }
13
- @query_scope.browser.after_hooks.add(reset_doc)
29
+ return super unless @nokogiri || @regex
30
+ @query_scope.browser.doc ||= Nokogiri::HTML(@query_scope.html).tap { |d| d.css('script').remove }
14
31
 
15
- find_first_by_multiple
32
+ elements = find_all_by_multiple
33
+ @nokogiri ? elements : elements.map { |element| nokogiri_to_watir element }
34
+ end
35
+
36
+ # Is only used when there is no regex, index or visibility locators
37
+ def locate_element(how, what)
38
+ return super unless @nokogiri
39
+
40
+ el = @query_scope.browser.doc.send("at_#{how}", what)
41
+ Watigiri::Element.new element: el, selector: {how => what}
42
+ end
43
+
44
+ # "how" can only be :css or :xpath
45
+ def locate_elements(how, what, _scope = @query_scope.wd)
46
+ return super unless (@nokogiri || @regex) && @query_scope.is_a?(Watir::Browser)
47
+
48
+ @query_scope.browser.doc.send(how, what).map do |el|
49
+ Watigiri::Element.new element: el, selector: {how => what}
16
50
  end
51
+ end
17
52
 
18
- def locate_element(how, what)
19
- unless @nokogiri
20
- return ensure_scope_context.find_element(how, what)
21
- end
22
- case how
23
- when :css
24
- @query_scope.browser.doc.at_css(what)
25
- when :xpath
26
- @query_scope.browser.doc.at_xpath(what)
27
- end
53
+ def filter_elements noko_elements, visible, idx, number
54
+ return super unless @nokogiri || @regex
55
+ return super if noko_elements.first.is_a?(Selenium::WebDriver::Element)
56
+
57
+ unless visible.nil?
58
+ noko_elements.select! { |el| visible == nokogiri_to_watir(el.element).visible? }
28
59
  end
60
+ number == :single ? noko_elements[idx || 0] : noko_elements
61
+ end
29
62
 
30
- def locate_elements(how, what, _scope = nil)
31
- unless @nokogiri
32
- return ensure_scope_context.find_elements(how, what)
33
- end
34
- case how
35
- when :css
36
- @query_scope.browser.doc.css(what).to_a
37
- when :xpath
38
- @query_scope.browser.doc.xpath(what).to_a
39
- end
63
+ def filter_elements_by_regex(noko_elements, rx_selector, method)
64
+ return if noko_elements.empty?
65
+ return super if noko_elements.first.is_a?(Selenium::WebDriver::Element)
66
+
67
+ if @nokogiri || !@regex
68
+ return noko_elements.__send__(method) { |el| matches_selector?(el.element, rx_selector) }
40
69
  end
41
70
 
42
- def fetch_value(element, how)
43
- return super unless @nokogiri
44
- case how
45
- when :text
46
- element.inner_text
47
- when :tag_name
48
- element.name.to_s.downcase
49
- when :href
50
- (href = element.attribute('href')) && href.to_s.strip
51
- else
52
- element.attribute(how.to_s.tr("_", "-")).to_s
71
+ selenium_elements = ensure_scope_context.find_elements(noko_elements.first.selector)
72
+
73
+ if method == :select
74
+ selenium_elements.zip(noko_elements).each_with_object([]) do |els, array|
75
+ array << els.first if matches_selector?(els.last.element, rx_selector)
53
76
  end
77
+ else
78
+ index = noko_elements.find_index { |el| matches_selector?(el.element, rx_selector) }
79
+ index.nil? ? nil : selenium_elements[index]
54
80
  end
81
+ end
55
82
 
56
- # TODO remove after https://github.com/watir/watir/pull/630
57
- def find_first_by_multiple
58
- selector = selector_builder.normalized_selector
83
+ def fetch_value(element, how)
84
+ return super unless @nokogiri || @regex
85
+ return super if element.is_a?(Selenium::WebDriver::Element)
86
+ case how
87
+ when :text
88
+ element.inner_text
89
+ when :tag_name
90
+ element.name.to_s.downcase
91
+ when :href
92
+ (href = element.attribute('href')) && href.to_s.strip
93
+ else
94
+ element.attribute(how.to_s.tr("_", "-")).to_s
95
+ end
96
+ end
59
97
 
60
- idx = selector.delete(:index) unless selector[:adjacent]
61
- visible = selector.delete(:visible)
98
+ def nokogiri_to_watir(element)
99
+ return element if element.is_a?(Selenium::WebDriver::Element)
100
+ se_element = nokogiri_to_selenium(element)
101
+ tag = element.name
102
+ Watir.element_class_for(tag).new(@query_scope, element: se_element)
103
+ end
62
104
 
63
- how, what = selector_builder.build(selector)
105
+ def nokogiri_to_selenium(element)
106
+ return element if element.is_a?(Selenium::WebDriver::Element)
107
+ tag = element.name
108
+ index = @query_scope.browser.doc.xpath("//#{tag}").find_index { |el| el == element }
109
+ Watir::Element.new(@query_scope, index: index, tag_name: tag).wd
110
+ end
64
111
 
65
- if how
66
- # could build xpath/css for selector
67
- if idx || !visible.nil?
68
- idx ||= 0
69
- elements = locate_elements(how, what)
70
- elements = elements.select { |el| visible == el.displayed? } unless visible.nil?
71
- elements[idx] unless elements.nil?
72
- else
73
- locate_element(how, what)
74
- end
75
- else
76
- # can't use xpath, probably a regexp in there
77
- if idx || !visible.nil?
78
- idx ||= 0
79
- elements = wd_find_by_regexp_selector(selector, :select)
80
- elements = elements.select { |el| visible == el.displayed? } unless visible.nil?
81
- elements[idx] unless elements.nil?
82
- else
83
- wd_find_by_regexp_selector(selector, :find)
84
- end
85
- end
112
+ def label_from_text(label_exp)
113
+ # TODO: this won't work correctly if @wd is a sub-element
114
+ elements = locate_elements(:xpath, '//label')
115
+ return super if elements.any? { |el| el.is_a? Selenium::WebDriver::Element }
116
+ element = elements.find do |el|
117
+ matches_selector?(el.element, text: label_exp)
86
118
  end
119
+ element.nil? ? nil : element.element
120
+ end
87
121
 
88
- # TODO Remove after https://github.com/watir/watir/pull/630
89
- def wd_find_by_regexp_selector(selector, method = :find)
90
- query_scope = ensure_scope_context
91
- rx_selector = delete_regexps_from(selector)
92
-
93
- if rx_selector.key?(:label) && selector_builder.should_use_label_element?
94
- label = label_from_text(rx_selector.delete(:label)) || return
95
- if (id = label.attribute(:for))
96
- selector[:id] = id
97
- else
98
- query_scope = label
99
- end
100
- end
122
+ def regex?
123
+ @selector.values.any? { |v| v.is_a?(Regexp) }
124
+ end
125
+ end
101
126
 
102
- how, what = selector_builder.build(selector)
103
127
 
104
- unless how
105
- raise Error, "internal error: unable to build Selenium selector from #{selector.inspect}"
106
- end
128
+ class Element
129
+ class Locator < Watir::Locators::Element::Locator
130
+ include LocatorHelpers
131
+ end
132
+ end
107
133
 
108
- if how == :xpath && can_convert_regexp_to_contains?
109
- rx_selector.each do |key, value|
110
- next if key == :tag_name || key == :text
134
+ class Button
135
+ class Locator < Watir::Locators::Button::Locator
136
+ include LocatorHelpers
137
+ end
138
+ end
111
139
 
112
- predicates = regexp_selector_to_predicates(key, value)
113
- what = "(#{what})[#{predicates.join(' and ')}]" unless predicates.empty?
140
+ class Cell
141
+ class Locator < Watir::Locators::Cell::Locator
142
+ include LocatorHelpers
143
+ end
144
+ end
145
+
146
+ class Row
147
+ class Locator < Watir::Locators::Row::Locator
148
+ include LocatorHelpers
149
+ end
150
+ end
151
+
152
+ class TextArea
153
+ class Locator < Watir::Locators::TextArea::Locator
154
+ include LocatorHelpers
155
+
156
+ def regex?
157
+ @selector.any? { |k, v| v.is_a?(Regexp) && k != :value }
158
+ end
159
+ end
160
+ end
161
+
162
+ class TextField
163
+ class Locator < Watir::Locators::TextField::Locator
164
+ include LocatorHelpers
165
+
166
+ def matches_selector?(element, rx_selector)
167
+ return super if element.is_a? Selenium::WebDriver::Element
168
+ rx_selector = rx_selector.dup
169
+
170
+ tag_name = element.name.downcase
171
+
172
+ [:text, :value, :label].each do |key|
173
+ if rx_selector.key?(key)
174
+ correct_key = tag_name == 'input' ? :value : :text
175
+ rx_selector[correct_key] = rx_selector.delete(key)
114
176
  end
115
177
  end
116
178
 
117
- elements = locate_elements(how, what, query_scope)
118
- elements.__send__(method) { |el| matches_selector?(el, rx_selector) }
179
+ rx_selector.all? do |how, what|
180
+ what === fetch_value(element, how)
181
+ end
119
182
  end
120
183
 
121
- # TODO Remove after https://github.com/watir/watir/pull/630
122
- def ensure_scope_context
123
- @query_scope.wd
184
+ def regex?
185
+ @selector.any? { |k, v| v.is_a?(Regexp) && k != :value }
124
186
  end
125
-
126
187
  end
127
188
  end
128
189
  end
@@ -1,14 +1,45 @@
1
1
  module Watigiri
2
2
  module Locators
3
+ module SelectorHelpers
4
+ def normalized_selector
5
+ @selector.delete(:nokogiri)
6
+ super
7
+ end
8
+ end
9
+
3
10
  class Element
4
11
  class SelectorBuilder < Watir::Locators::Element::SelectorBuilder
12
+ include SelectorHelpers
13
+ end
14
+ end
15
+
16
+ class Button
17
+ class SelectorBuilder < Watir::Locators::Button::SelectorBuilder
18
+ include SelectorHelpers
19
+ end
20
+ end
5
21
 
6
- def initialize(query_scope, selector, attribute_list)
7
- attribute_list << :nokogiri
8
- super
9
- @selector.delete :nokogiri
10
- end
22
+ class Cell
23
+ class SelectorBuilder < Watir::Locators::Cell::SelectorBuilder
24
+ include SelectorHelpers
25
+ end
26
+ end
27
+
28
+ class Row
29
+ class SelectorBuilder < Watir::Locators::Row::SelectorBuilder
30
+ include SelectorHelpers
31
+ end
32
+ end
33
+
34
+ class TextArea
35
+ class SelectorBuilder < Watir::Locators::TextArea::SelectorBuilder
36
+ include SelectorHelpers
37
+ end
38
+ end
11
39
 
40
+ class TextField
41
+ class SelectorBuilder < Watir::Locators::TextField::SelectorBuilder
42
+ include SelectorHelpers
12
43
  end
13
44
  end
14
45
  end
@@ -0,0 +1,6 @@
1
+ #!/bin/bash
2
+
3
+ set -e
4
+ set -x
5
+
6
+ sh -e /etc/init.d/xvfb start
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
 
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = "watigiri"
7
- spec.version = "0.1.0"
7
+ spec.version = "0.2.0"
8
8
  spec.authors = ["Titus Fortner"]
9
9
  spec.email = ["titusfortner@gmail.com"]
10
10
 
@@ -26,8 +26,8 @@ with Nokogiri calls where designated.
26
26
  spec.add_development_dependency "bundler", "~> 1.15"
27
27
  spec.add_development_dependency "rake", "~> 10.0"
28
28
  spec.add_development_dependency "rspec", "~> 3.0"
29
- spec.add_development_dependency "webdrivers", "~> 2.0"
29
+ spec.add_development_dependency "webdrivers", "~> 3.0"
30
30
 
31
- spec.add_runtime_dependency "watir"
31
+ spec.add_runtime_dependency "watir", "~> 6.8", ">= 6.8.2"
32
32
  spec.add_runtime_dependency "nokogiri"
33
33
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: watigiri
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Titus Fortner
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-08-21 00:00:00.000000000 Z
11
+ date: 2017-09-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -58,28 +58,34 @@ dependencies:
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '2.0'
61
+ version: '3.0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '2.0'
68
+ version: '3.0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: watir
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '6.8'
73
76
  - - ">="
74
77
  - !ruby/object:Gem::Version
75
- version: '0'
78
+ version: 6.8.2
76
79
  type: :runtime
77
80
  prerelease: false
78
81
  version_requirements: !ruby/object:Gem::Requirement
79
82
  requirements:
83
+ - - "~>"
84
+ - !ruby/object:Gem::Version
85
+ version: '6.8'
80
86
  - - ">="
81
87
  - !ruby/object:Gem::Version
82
- version: '0'
88
+ version: 6.8.2
83
89
  - !ruby/object:Gem::Dependency
84
90
  name: nokogiri
85
91
  requirement: !ruby/object:Gem::Requirement
@@ -116,7 +122,7 @@ files:
116
122
  - lib/watigiri.rb
117
123
  - lib/watigiri/locators/element/locator.rb
118
124
  - lib/watigiri/locators/element/selector_builder.rb
119
- - lib/watigiri/locators/element/validator.rb
125
+ - support/travis.sh
120
126
  - watigiri.gemspec
121
127
  homepage: http://github.com/titusfortner/watigiri
122
128
  licenses:
@@ -1,8 +0,0 @@
1
- module Watigiri
2
- module Locators
3
- class Element
4
- class Validator < Watir::Locators::Element::Validator
5
- end
6
- end
7
- end
8
- end