watigiri 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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