unobtainium-multiwait 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 4c0be5b0d21564f39c671a3ce93b033694a1be33
4
+ data.tar.gz: edcd6536595cce853ebf59d5cbdb7dffb9a1ee38
5
+ SHA512:
6
+ metadata.gz: b61d7186397ad199a2d9ce591d3ccb3f03943cb15a3ef9b32799cf6921a66d0ca730cd715d7f46755bcba1993f0bc701f6ad8ddd3f5f1e4e0db62f7c0a7e4499
7
+ data.tar.gz: 8b76fb36e10b0382d8df528cb163a1e8c86e86f980615b7f773971374fcf47b17c380b8d2e5cde99303e1ed109856e5cf4ca56deb1becaa72136bc234f38168f
data/.codeclimate.yml ADDED
@@ -0,0 +1,28 @@
1
+ ---
2
+ engines:
3
+ bundler-audit:
4
+ enabled: true
5
+ duplication:
6
+ enabled: true
7
+ config:
8
+ languages:
9
+ - ruby
10
+ - javascript
11
+ - python
12
+ - php
13
+ fixme:
14
+ enabled: true
15
+ rubocop:
16
+ enabled: true
17
+ ratings:
18
+ paths:
19
+ - Gemfile.lock
20
+ - "**.inc"
21
+ - "**.js"
22
+ - "**.jsx"
23
+ - "**.module"
24
+ - "**.php"
25
+ - "**.py"
26
+ - "**.rb"
27
+ exclude_paths:
28
+ - spec/
data/.gitignore ADDED
@@ -0,0 +1,42 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /spec/examples.txt
9
+ /test/tmp/
10
+ /test/version_tmp/
11
+ /tmp/
12
+
13
+ ## Specific to RubyMotion:
14
+ .dat*
15
+ .repl_history
16
+ build/
17
+
18
+ ## Documentation cache and generated files:
19
+ /.yardoc/
20
+ /_yardoc/
21
+ /doc/
22
+ /rdoc/
23
+
24
+ ## Environment normalization:
25
+ /.bundle/
26
+ /vendor/bundle
27
+ /lib/bundler/man/
28
+
29
+ # for a library or gem, you might want to ignore these files since the code is
30
+ # intended to run in multiple environments; otherwise, check them in:
31
+ # Gemfile.lock
32
+ # .ruby-version
33
+ # .ruby-gemset
34
+
35
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
36
+ .rvmrc
37
+
38
+ # Editor files
39
+ .*.sw*
40
+
41
+ # Firefox driver
42
+ C:\\nppdf32Log\\debuglog.txt
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.rubocop.yml ADDED
@@ -0,0 +1,72 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.2
3
+
4
+ # Metrics
5
+
6
+ Metrics/LineLength:
7
+ Max: 83
8
+ Details: >-
9
+ Line length of 80 is ideal for readability and compatibility; we'll accept
10
+ an extra 3 for minor edge cases.
11
+
12
+ Metrics/MethodLength:
13
+ Max: 35
14
+
15
+ Metrics/BlockNesting:
16
+ Max: 5
17
+
18
+ Metrics/AbcSize:
19
+ Max: 50
20
+
21
+ Metrics/PerceivedComplexity:
22
+ Max: 15
23
+
24
+ Metrics/CyclomaticComplexity:
25
+ Max: 15
26
+
27
+ Metrics/ClassLength:
28
+ Max: 300
29
+
30
+ Metrics/ModuleLength:
31
+ Max: 300
32
+
33
+ # Style
34
+
35
+ Style/StringLiterals:
36
+ Enabled: false
37
+
38
+ Style/ConditionalAssignment:
39
+ Enabled: false
40
+
41
+ Style/EmptyLinesAroundModuleBody:
42
+ Enabled: false
43
+
44
+ Style/AndOr:
45
+ Enabled: false
46
+
47
+ Style/Not:
48
+ Enabled: false
49
+
50
+ Style/NegatedIf:
51
+ Enabled: false
52
+
53
+ Style/RedundantReturn:
54
+ Enabled: false
55
+
56
+ Style/IfUnlessModifier:
57
+ Enabled: false
58
+
59
+ Style/TrailingCommaInLiteral:
60
+ Enabled: false
61
+
62
+ Style/FirstParameterIndentation:
63
+ Enabled: false
64
+
65
+ Style/TrailingUnderscoreVariable:
66
+ Enabled: false
67
+
68
+ Style/NumericLiterals:
69
+ Enabled: false
70
+
71
+ Style/FileName:
72
+ Enabled: false
data/.travis.yml ADDED
@@ -0,0 +1,8 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0
4
+ - 2.1
5
+ - 2.2
6
+ addons:
7
+ code_climate:
8
+ repo_token: 80dc28586def5dc07809b4f5171d54d9087f446ca85092046258618eb27c814e
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in unobtainium-multiwait.gemspec
4
+ gemspec
5
+
6
+ gem "codeclimate-test-reporter", group: :test, require: nil
data/Gemfile.lock ADDED
@@ -0,0 +1,81 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ unobtainium-multiwait (0.1.0)
5
+ unobtainium (~> 0.5)
6
+ unobtainium-multifind (~> 0.2)
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ ast (2.2.0)
12
+ childprocess (0.5.9)
13
+ ffi (~> 1.0, >= 1.0.11)
14
+ codeclimate-test-reporter (0.5.0)
15
+ simplecov (>= 0.7.1, < 1.0.0)
16
+ diff-lcs (1.2.5)
17
+ docile (1.1.5)
18
+ ffi (1.9.10)
19
+ json (1.8.3)
20
+ parser (2.3.1.0)
21
+ ast (~> 2.2)
22
+ phantomjs (2.1.1.0)
23
+ powerpack (0.1.1)
24
+ rainbow (2.1.0)
25
+ rake (11.1.2)
26
+ rspec (3.4.0)
27
+ rspec-core (~> 3.4.0)
28
+ rspec-expectations (~> 3.4.0)
29
+ rspec-mocks (~> 3.4.0)
30
+ rspec-core (3.4.4)
31
+ rspec-support (~> 3.4.0)
32
+ rspec-expectations (3.4.0)
33
+ diff-lcs (>= 1.2.0, < 2.0)
34
+ rspec-support (~> 3.4.0)
35
+ rspec-mocks (3.4.1)
36
+ diff-lcs (>= 1.2.0, < 2.0)
37
+ rspec-support (~> 3.4.0)
38
+ rspec-support (3.4.1)
39
+ rubocop (0.39.0)
40
+ parser (>= 2.3.0.7, < 3.0)
41
+ powerpack (~> 0.1)
42
+ rainbow (>= 1.99.1, < 3.0)
43
+ ruby-progressbar (~> 1.7)
44
+ unicode-display_width (~> 1.0, >= 1.0.1)
45
+ ruby-progressbar (1.8.0)
46
+ rubyzip (1.2.0)
47
+ selenium-webdriver (2.53.0)
48
+ childprocess (~> 0.5)
49
+ rubyzip (~> 1.0)
50
+ websocket (~> 1.0)
51
+ simplecov (0.11.2)
52
+ docile (~> 1.1.0)
53
+ json (~> 1.8)
54
+ simplecov-html (~> 0.10.0)
55
+ simplecov-html (0.10.0)
56
+ sys-proctable (1.0.0)
57
+ unicode-display_width (1.0.5)
58
+ unobtainium (0.5.0)
59
+ sys-proctable (~> 1.0)
60
+ unobtainium-multifind (0.2.0)
61
+ unobtainium (~> 0.5)
62
+ websocket (1.2.3)
63
+ yard (0.8.7.6)
64
+
65
+ PLATFORMS
66
+ ruby
67
+
68
+ DEPENDENCIES
69
+ bundler (~> 1.12)
70
+ codeclimate-test-reporter
71
+ phantomjs
72
+ rake (~> 11.1)
73
+ rspec (~> 3.4)
74
+ rubocop (~> 0.39)
75
+ selenium-webdriver
76
+ simplecov (~> 0.11)
77
+ unobtainium-multiwait!
78
+ yard (~> 0.8)
79
+
80
+ BUNDLED WITH
81
+ 1.12.1
data/LICENSE ADDED
@@ -0,0 +1,30 @@
1
+ Copyright (c) Jens Finkhaeuser (http://finkhaeuser.de/) and other
2
+ unobtainium-multiwait contributors. All rights not covered below are reserved.
3
+
4
+ The MIT +no-false-attribs License (MITNFA)
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to
8
+ deal in the Software without restriction, including without limitation the
9
+ rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10
+ sell copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in
14
+ all copies or substantial portions of the Software.
15
+
16
+ Distributions of all or part of the Software intended to be used by the
17
+ recipients as they would use the unmodified Software, containing modifications
18
+ that substantially alter, remove, or disable functionality of the Software,
19
+ outside of the documented configuration mechanisms provided by the Software,
20
+ shall be modified such that the Original Author's bug reporting email addresses
21
+ and urls are either replaced with the contact information of the parties
22
+ responsible for the changes, or removed entirely.
23
+
24
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
30
+ IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # unobtainium-multiwait
2
+
3
+ This gem provides a driver module for [unobtainium](https://github.com/jfinkhaeuser/unobtainium)
4
+ allowing for more easily finding (one of) multiple elements.
5
+
6
+ [![Gem Version](https://badge.fury.io/rb/unobtainium-multiwait.svg)](https://badge.fury.io/rb/unobtainium-multiwait)
7
+ [![Build status](https://travis-ci.org/jfinkhaeuser/unobtainium-multiwait.svg?branch=master)](https://travis-ci.org/jfinkhaeuser/unobtainium-multiwait)
8
+ [![Code Climate](https://codeclimate.com/github/jfinkhaeuser/unobtainium-multiwait/badges/gpa.svg)](https://codeclimate.com/github/jfinkhaeuser/unobtainium-multiwait)
9
+ [![Test Coverage](https://codeclimate.com/github/jfinkhaeuser/unobtainium-multiwait/badges/coverage.svg)](https://codeclimate.com/github/jfinkhaeuser/unobtainium-multiwait/coverage)
10
+
11
+ To use it, require it after requiring unobtainium, then create the any driver
12
+ with a Selenium API:
13
+
14
+ ```ruby
15
+ require 'unobtainium'
16
+ require 'unobtainium-multiwait'
17
+
18
+ include Unobtainium::World
19
+
20
+ driver.navigate.to('http://finkhaeuser.de')
21
+
22
+ elems = driver.multiwait({ xpath: '//some-element' },
23
+ { xpath: '//other-element' },
24
+ timeout: 10)
25
+
26
+ # Entries will be nil if nothing is found by these xpaths before the
27
+ # timeout expires.
28
+ puts elems.length # => 2
29
+ ```
data/Rakefile ADDED
@@ -0,0 +1,25 @@
1
+ # Rubocop
2
+ require 'rubocop/rake_task'
3
+ RuboCop::RakeTask.new(:rubocop)
4
+
5
+ # Rspec
6
+ require 'rspec/core/rake_task'
7
+ RSpec::Core::RakeTask.new(:rspec)
8
+
9
+ # Documentation
10
+ require 'yard'
11
+ YARD::Rake::YardocTask.new do |t|
12
+ t.files = ['lib/**/*.rb']
13
+ t.options = ['-m', 'markdown']
14
+ t.stats_options = ['--list-undoc']
15
+ end
16
+
17
+ # Combined test task
18
+ desc "Test all the things!"
19
+ task :test do
20
+ Rake::Task[:rubocop].invoke
21
+ Rake::Task[:rspec].invoke
22
+ end
23
+
24
+ # Default is the test task
25
+ task default: :test
@@ -0,0 +1,186 @@
1
+ # coding: utf-8
2
+ #
3
+ # unobtainium-multiwait
4
+ # https://github.com/jfinkhaeuser/unobtainium-multiwait
5
+ #
6
+ # Copyright (c) 2016 Jens Finkhaeuser and other unobtainium-multiwait contributors.
7
+ # All rights reserved.
8
+ #
9
+
10
+ require 'unobtainium'
11
+ require 'unobtainium-multifind'
12
+
13
+ module Unobtainium
14
+ module MultiWait
15
+ ##
16
+ # Driver module implementing multi wait functionality.
17
+ module DriverModule
18
+ ##
19
+ # Default options. This hash is also used to detect if any of the Hashes
20
+ # passed to #multiwait is an options Hash; it is considered one if it
21
+ # contains any of the keys specified here.
22
+ DEFAULT_OPTIONS = {
23
+ # If true, raises on error instead of returning nil
24
+ raise_on_error: false,
25
+ # If true, returns the error object instead of nil
26
+ return_errors: false,
27
+ # If :all is specified, the method waits for all elements to
28
+ # appear or times out.
29
+ # If :first is specified, the method returns when the first
30
+ # element appears.
31
+ wait_for: :all,
32
+ # Defaults to only finding :displayed? elements. You can use any method
33
+ # that Selenium::WebDriver::Element responds to, or :exists? if you only
34
+ # care whether the element exists.
35
+ check_element: :displayed?,
36
+ # The default wait timeout in seconds.
37
+ timeout: 10,
38
+ }.freeze
39
+
40
+ class << self
41
+ ##
42
+ # Returns true if the implementation has `#find_element`, false
43
+ # otherwise.
44
+ def matches?(impl)
45
+ return impl.respond_to?(:find_element)
46
+ end
47
+ end # class << self
48
+
49
+ ##
50
+ # Current options for multiwait
51
+ attr_accessor :multiwait_options
52
+ @multiwait_options = DEFAULT_OPTIONS
53
+
54
+ ##
55
+ # Wait for multiple elements. Each argument is a Hash of selector options
56
+ # that are passed to #find_element. If one argument contains keys from
57
+ # the DEFAULT_OPTIONS Hash, it is instead treated as an options Hash for
58
+ # the #multiwait method.
59
+ # @return Array of found elements or nil entries if no matching element
60
+ # was found.
61
+ # FIXME: recheck this!
62
+ def multiwait(*args)
63
+ # Parse options
64
+ options, selectors = multiwait_parse_options(*args)
65
+
66
+ # Pass some options to multifind
67
+ multifind_opts = {
68
+ raise_on_error: options[:raise_on_error],
69
+ return_errors: options[:return_error],
70
+ check_element: options[:check_element],
71
+ }
72
+
73
+ # Wait for elements
74
+ results = []
75
+ wait = ::Selenium::WebDriver::Wait.new(timeout: options[:timeout])
76
+ begin
77
+ wait.until do
78
+ results = multifind(*selectors, multifind_opts)
79
+ got_it, results = multiwait_filter_results(options, results)
80
+ if got_it
81
+ return results
82
+ end
83
+ end
84
+ rescue ::Selenium::WebDriver::Error::TimeOutError => err
85
+ if options[:raise_on_error]
86
+ raise
87
+ end
88
+ if options[:return_errors]
89
+ results.map! { |result| result.nil? ? err : result }
90
+ end
91
+ end
92
+
93
+ return results
94
+ end
95
+
96
+ alias wait multiwait
97
+
98
+ private
99
+
100
+ def multiwait_filter_results(options, results)
101
+ if options[:wait_for] != :first
102
+ got_it = true
103
+ results.each do |result|
104
+ # rubocop:disable Style/Next
105
+ if result.nil? or
106
+ result.is_a?(::Selenium::WebDriver::Error::NoSuchElementError)
107
+ got_it = false
108
+ break
109
+ end
110
+ # rubocop:enable Style/Next
111
+ end
112
+ return got_it, results
113
+ end
114
+
115
+ # If we want to exit on the first found result, we'll have to go and
116
+ # find non-error results here.
117
+ results.each do |result|
118
+ if not result.nil? and
119
+ not result.is_a?(::Selenium::WebDriver::Error::NoSuchElementError)
120
+ return true, [result]
121
+ end
122
+ end
123
+
124
+ return false, []
125
+ end
126
+
127
+ ##
128
+ # Distinguishes between option hashes and selectors by detecting Hash
129
+ # arguments with keys from DEFAULT_OPTIONS. Those are considered to be
130
+ # options, and merged with any preceding option hashes, where latter
131
+ # occurrences overwrite earlier ones.
132
+ def multiwait_parse_options(*args)
133
+ # Sanity
134
+ if @multiwait_options.nil?
135
+ @multiwait_options = DEFAULT_OPTIONS
136
+ end
137
+
138
+ # Distinguish between options and selectors
139
+ options = {}
140
+ selectors = []
141
+ args.each do |arg|
142
+ # Let the underlying API handle all non-Hashes
143
+ if not arg.is_a?(Hash)
144
+ selectors << arg
145
+ next
146
+ end
147
+
148
+ # See if it contains any of the keys we care about
149
+ option_keys = DEFAULT_OPTIONS.keys
150
+ diff = option_keys - arg.keys
151
+ if diff != option_keys
152
+ options.merge!(arg)
153
+ next
154
+ end
155
+
156
+ selectors << arg
157
+ end
158
+ options = @multiwait_options.merge(options)
159
+ options = DEFAULT_OPTIONS.merge(options)
160
+
161
+ # Ensure that the 'wait_for' option contains correct
162
+ # values only.
163
+ if not [:all, :first].include?(options[:wait_for])
164
+ raise ArgumentError, ":wait_for option must be either :all or :first, "\
165
+ "but is: #{options[:wait_for]}"
166
+ end
167
+
168
+ # Ensure that 'check_element' contains only valid options.
169
+ elem_klass = ::Selenium::WebDriver::Element
170
+ if options[:check_element] != :exists? and
171
+ not elem_klass.instance_methods.include?(options[:check_element])
172
+ raise ArgumentError, ":check_element must either be :exists? or "\
173
+ "a boolean method that ::Selenium::WebDriver::Element responds to, "\
174
+ "but got: #{options[:check_element]}"
175
+ end
176
+
177
+ return options, selectors
178
+ end
179
+
180
+ end # module DriverModule
181
+ end # module MultiWait
182
+ end # module Unobtainium
183
+
184
+ ::Unobtainium::Driver.register_module(
185
+ ::Unobtainium::MultiWait::DriverModule,
186
+ __FILE__)
@@ -0,0 +1,14 @@
1
+ # coding: utf-8
2
+ #
3
+ # unobtainium-multiwait
4
+ # https://github.com/jfinkhaeuser/unobtainium-multiwait
5
+ #
6
+ # Copyright (c) 2016 Jens Finkhaeuser and other unobtainium-multiwait contributors.
7
+ # All rights reserved.
8
+ #
9
+ module Unobtainium
10
+ module MultiWait
11
+ # The current release version
12
+ VERSION = "0.1.0".freeze
13
+ end # module MultiWait
14
+ end # module Unobtainium
@@ -0,0 +1,10 @@
1
+ # coding: utf-8
2
+ #
3
+ # unobtainium-multiwait
4
+ # https://github.com/jfinkhaeuser/unobtainium-multiwait
5
+ #
6
+ # Copyright (c) 2016 Jens Finkhaeuser and other unobtainium-multiwait contributors.
7
+ # All rights reserved.
8
+ #
9
+
10
+ require 'unobtainium-multiwait/multiwait'
@@ -0,0 +1,15 @@
1
+ <foo>
2
+ <bar>
3
+ <something>else</something></bar>
4
+ <hidden style="display: none"></hidden>
5
+ <appears id="appears" style="display: none">boo!</appears>
6
+ <appears-too-late id="late" style="display: none">aah!</appears-too-late>
7
+ <script>
8
+ setTimeout(function() {
9
+ document.getElementById("appears").style.display = "block";
10
+ }, 3000);
11
+ setTimeout(function() {
12
+ document.getElementById("late").style.display = "block";
13
+ }, 12000);
14
+ </script>
15
+ <foo>
@@ -0,0 +1,212 @@
1
+ # coding: utf-8
2
+ #
3
+ # unobtainium-multiwait
4
+ # https://github.com/jfinkhaeuser/unobtainium-multiwait
5
+ #
6
+ # Copyright (c) 2016 Jens Finkhaeuser and other unobtainium-multiwait contributors.
7
+ # All rights reserved.
8
+ #
9
+ require 'spec_helper'
10
+
11
+ require 'unobtainium'
12
+
13
+ DRIVER = :headless
14
+ # DRIVER = :firefox
15
+ TEST_URL = 'file://' + Dir.pwd + '/spec/data/foo.html'
16
+
17
+ class Tester
18
+ include ::Unobtainium::World
19
+ end # class Tester
20
+
21
+ describe 'Unobtainium::MultiWait::DriverModule' do
22
+ before :each do
23
+ @tester = Tester.new
24
+ end
25
+
26
+ describe "module interface" do
27
+ it "passes unobtainium's interface checks" do
28
+ expect do
29
+ require 'unobtainium-multiwait'
30
+ end.to_not raise_error(LoadError)
31
+ end
32
+
33
+ it "exposes wait methods" do
34
+ drv = @tester.driver(DRIVER)
35
+ expect(drv.respond_to?(:wait)).to be_truthy
36
+ expect(drv.respond_to?(:multiwait)).to be_truthy
37
+ end
38
+ end
39
+
40
+ describe "wait functionality" do
41
+ before do
42
+ require 'unobtainium-multiwait'
43
+ end
44
+
45
+ it "can wait for single element that already exists" do
46
+ drv = @tester.driver(DRIVER)
47
+ drv.navigate.to(TEST_URL)
48
+ drv.navigate.refresh
49
+ elem = drv.wait(xpath: '//foo/bar')
50
+ expect(elem).not_to be_nil
51
+ expect(elem).not_to be_empty
52
+ expect(elem.length).to eql 1
53
+ expect(elem[0]).not_to be_nil
54
+ end
55
+
56
+ it "can wait for multiple elements that already exist" do
57
+ drv = @tester.driver(DRIVER)
58
+ drv.navigate.to(TEST_URL)
59
+ drv.navigate.refresh
60
+ # rubocop:disable Style/BracesAroundHashParameters
61
+ elem = drv.wait({ xpath: '//foo/bar' },
62
+ { xpath: '//something' })
63
+ # rubocop:enable Style/BracesAroundHashParameters
64
+ expect(elem).not_to be_nil
65
+ expect(elem).not_to be_empty
66
+ expect(elem.length).to eql 2
67
+ expect(elem[0]).not_to be_nil
68
+ expect(elem[1]).not_to be_nil
69
+ end
70
+
71
+ it "returns an element if it appears on time" do
72
+ drv = @tester.driver(DRIVER)
73
+ drv.navigate.to(TEST_URL)
74
+ drv.navigate.refresh
75
+ elem = drv.wait(xpath: '//foo/appears')
76
+ expect(elem).not_to be_nil
77
+ expect(elem).not_to be_empty
78
+ expect(elem.length).to eql 1
79
+ expect(elem[0]).not_to be_nil
80
+ end
81
+
82
+ it "times out when an element can't be found in time" do
83
+ drv = @tester.driver(DRIVER)
84
+ drv.navigate.to(TEST_URL)
85
+ drv.navigate.refresh
86
+ elem = drv.wait(xpath: '//foo/appears-too-late')
87
+ expect(elem).not_to be_nil
88
+ expect(elem).not_to be_empty
89
+ expect(elem.length).to eql 1
90
+ expect(elem[0]).to be_nil
91
+ end
92
+
93
+ it "returns all elements that can be found on time" do
94
+ drv = @tester.driver(DRIVER)
95
+ drv.navigate.to(TEST_URL)
96
+ drv.navigate.refresh
97
+ # rubocop:disable Style/BracesAroundHashParameters
98
+ elem = drv.wait({ xpath: '//foo/bar' },
99
+ { xpath: '//foo/appears' },
100
+ { xpath: '//foo/appears-too-late' })
101
+ # rubocop:enable Style/BracesAroundHashParameters
102
+ expect(elem).not_to be_nil
103
+ expect(elem).not_to be_empty
104
+ expect(elem.length).to eql 3
105
+ expect(elem[0]).not_to be_nil
106
+ expect(elem[1]).not_to be_nil
107
+ expect(elem[2]).to be_nil
108
+ end
109
+
110
+ it "returns the first found element if :wait_for == :first" do
111
+ drv = @tester.driver(DRIVER)
112
+ drv.navigate.to(TEST_URL)
113
+ drv.navigate.refresh
114
+ # rubocop:disable Style/BracesAroundHashParameters
115
+ elem = drv.wait({ xpath: '//foo/appears' },
116
+ { xpath: '//foo/appears-too-late' },
117
+ { wait_for: :first })
118
+ # rubocop:enable Style/BracesAroundHashParameters
119
+ expect(elem).not_to be_nil
120
+ expect(elem).not_to be_empty
121
+ expect(elem.length).to eql 1
122
+ expect(elem[0]).not_to be_nil
123
+ end
124
+
125
+ it "passes non-hash arguments without touching them" do
126
+ drv = @tester.driver(DRIVER)
127
+ drv.navigate.to(TEST_URL)
128
+ expect do
129
+ drv.wait(42) # not a valid selector for selenium
130
+ end.to raise_error
131
+ end
132
+ end
133
+
134
+ describe "wait options" do
135
+ before do
136
+ require 'unobtainium-multiwait'
137
+ end
138
+
139
+ it "can throw on errors" do
140
+ drv = @tester.driver(DRIVER)
141
+ drv.navigate.to(TEST_URL)
142
+ # rubocop:disable Style/BracesAroundHashParameters
143
+ expect do
144
+ drv.wait({ xpath: '//does-not-exist' },
145
+ { xpath: '//foo' },
146
+ { raise_on_error: true })
147
+ end.to raise_error(::Selenium::WebDriver::Error::TimeOutError)
148
+ # rubocop:enable Style/BracesAroundHashParameters
149
+ end
150
+
151
+ it "can return errors" do
152
+ drv = @tester.driver(DRIVER)
153
+ drv.navigate.to(TEST_URL)
154
+ # rubocop:disable Style/BracesAroundHashParameters
155
+ elems = drv.wait({ xpath: '//does-not-exist' },
156
+ { xpath: '//foo' },
157
+ { return_errors: true })
158
+ # rubocop:enable Style/BracesAroundHashParameters
159
+ expect(elems).not_to be_nil
160
+ expect(elems).not_to be_empty
161
+ expect(elems.length).to eql 2
162
+ expect(elems[0]).not_to be_nil
163
+ expect(elems[1]).not_to be_nil
164
+ is_error = elems[0].is_a?(
165
+ ::Selenium::WebDriver::Error::TimeOutError)
166
+ expect(is_error).to be_truthy
167
+ end
168
+
169
+ it "can honour instance options" do
170
+ drv = @tester.driver(DRIVER)
171
+ drv.navigate.to(TEST_URL)
172
+ drv.multiwait_options = { raise_on_error: true }
173
+ expect do
174
+ drv.wait(xpath: '//does-not-exist')
175
+ end.to raise_error(::Selenium::WebDriver::Error::TimeOutError)
176
+ end
177
+
178
+ it "validates :wait_for" do
179
+ drv = @tester.driver(DRIVER)
180
+ drv.navigate.to(TEST_URL)
181
+
182
+ # Good option
183
+ drv.multiwait_options = { wait_for: :all }
184
+ expect do
185
+ drv.wait(xpath: '//foo')
186
+ end.not_to raise_error
187
+
188
+ # Bad option
189
+ drv.multiwait_options = { wait_for: :bad }
190
+ expect do
191
+ drv.wait(xpath: '//foo')
192
+ end.to raise_error
193
+ end
194
+
195
+ it "validates :check_element" do
196
+ drv = @tester.driver(DRIVER)
197
+ drv.navigate.to(TEST_URL)
198
+
199
+ # Good option
200
+ drv.multiwait_options = { check_element: :exists? }
201
+ expect do
202
+ drv.wait(xpath: '//foo')
203
+ end.not_to raise_error
204
+
205
+ # Bad option
206
+ drv.multiwait_options = { check_element: :foobar }
207
+ expect do
208
+ drv.wait(xpath: '//foo')
209
+ end.to raise_error
210
+ end
211
+ end
212
+ end
@@ -0,0 +1,11 @@
1
+ # Only start CodeClimate from travis
2
+ if ENV['CODECLIMATE_REPO_TOKEN']
3
+ require 'codeclimate-test-reporter'
4
+ CodeClimate::TestReporter.start
5
+ end
6
+
7
+ # Always start SimpleCov
8
+ require 'simplecov'
9
+ SimpleCov.start do
10
+ # add_filter 'unobtainium/drivers'
11
+ end
@@ -0,0 +1,56 @@
1
+ # coding: utf-8
2
+ #
3
+ # unobtainium-multiwait
4
+ # https://github.com/jfinkhaeuser/unobtainium-multiwait
5
+ #
6
+ # Copyright (c) 2016 Jens Finkhaeuser and other unobtainium-multiwait contributors.
7
+ # All rights reserved.
8
+ #
9
+
10
+ lib = File.expand_path('../lib', __FILE__)
11
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
12
+ require 'unobtainium-multiwait/version'
13
+
14
+ # rubocop:disable Style/UnneededPercentQ, Style/ExtraSpacing
15
+ # rubocop:disable Style/SpaceAroundOperators
16
+ Gem::Specification.new do |spec|
17
+ spec.name = "unobtainium-multiwait"
18
+ spec.version = Unobtainium::MultiWait::VERSION
19
+ spec.authors = ["Jens Finkhaeuser"]
20
+ spec.email = ["jens@finkhaeuser.de"]
21
+ spec.description = %q(
22
+ This gem provides a driver module for unobtainium allowing for more easily
23
+ waiting for (one of) multiple elements to change state.
24
+
25
+ It is based on the unobtainium-multifind gem.
26
+ )
27
+ spec.summary = %q(
28
+ This gem provides a driver module for unobtainium allowing for more easily
29
+ waiting for (one of) multiple elements to change state.
30
+ )
31
+ spec.homepage = "https://github.com/jfinkhaeuser/unobtainium-multiwait"
32
+ spec.license = "MITNFA"
33
+
34
+ spec.files = `git ls-files -z`.split("\x0")
35
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
36
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
37
+ spec.require_paths = ["lib"]
38
+
39
+ spec.required_ruby_version = '>= 2.0'
40
+
41
+ spec.requirements = "Unobtainium driver implementing the Selenium API"
42
+
43
+ spec.add_development_dependency "bundler", "~> 1.12"
44
+ spec.add_development_dependency "rubocop", "~> 0.39"
45
+ spec.add_development_dependency "rake", "~> 11.1"
46
+ spec.add_development_dependency "rspec", "~> 3.4"
47
+ spec.add_development_dependency "simplecov", "~> 0.11"
48
+ spec.add_development_dependency "yard", "~> 0.8"
49
+ spec.add_development_dependency "selenium-webdriver"
50
+ spec.add_development_dependency "phantomjs"
51
+
52
+ spec.add_dependency "unobtainium", "~> 0.5"
53
+ spec.add_dependency "unobtainium-multifind", "~> 0.2"
54
+ end
55
+ # rubocop:enable Style/SpaceAroundOperators
56
+ # rubocop:enable Style/UnneededPercentQ, Style/ExtraSpacing
metadata ADDED
@@ -0,0 +1,209 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: unobtainium-multiwait
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Jens Finkhaeuser
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-05-09 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.12'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.12'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rubocop
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.39'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.39'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '11.1'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '11.1'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.4'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.4'
69
+ - !ruby/object:Gem::Dependency
70
+ name: simplecov
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '0.11'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '0.11'
83
+ - !ruby/object:Gem::Dependency
84
+ name: yard
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '0.8'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '0.8'
97
+ - !ruby/object:Gem::Dependency
98
+ name: selenium-webdriver
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: phantomjs
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: unobtainium
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '0.5'
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '0.5'
139
+ - !ruby/object:Gem::Dependency
140
+ name: unobtainium-multifind
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: '0.2'
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: '0.2'
153
+ description: "\n This gem provides a driver module for unobtainium allowing for
154
+ more easily\n waiting for (one of) multiple elements to change state.\n\n It
155
+ is based on the unobtainium-multifind gem.\n "
156
+ email:
157
+ - jens@finkhaeuser.de
158
+ executables: []
159
+ extensions: []
160
+ extra_rdoc_files: []
161
+ files:
162
+ - ".codeclimate.yml"
163
+ - ".gitignore"
164
+ - ".rspec"
165
+ - ".rubocop.yml"
166
+ - ".travis.yml"
167
+ - Gemfile
168
+ - Gemfile.lock
169
+ - LICENSE
170
+ - README.md
171
+ - Rakefile
172
+ - lib/unobtainium-multiwait.rb
173
+ - lib/unobtainium-multiwait/multiwait.rb
174
+ - lib/unobtainium-multiwait/version.rb
175
+ - spec/data/foo.html
176
+ - spec/module_spec.rb
177
+ - spec/spec_helper.rb
178
+ - unobtainium-multiwait.gemspec
179
+ homepage: https://github.com/jfinkhaeuser/unobtainium-multiwait
180
+ licenses:
181
+ - MITNFA
182
+ metadata: {}
183
+ post_install_message:
184
+ rdoc_options: []
185
+ require_paths:
186
+ - lib
187
+ required_ruby_version: !ruby/object:Gem::Requirement
188
+ requirements:
189
+ - - ">="
190
+ - !ruby/object:Gem::Version
191
+ version: '2.0'
192
+ required_rubygems_version: !ruby/object:Gem::Requirement
193
+ requirements:
194
+ - - ">="
195
+ - !ruby/object:Gem::Version
196
+ version: '0'
197
+ requirements:
198
+ - Unobtainium driver implementing the Selenium API
199
+ rubyforge_project:
200
+ rubygems_version: 2.4.5.1
201
+ signing_key:
202
+ specification_version: 4
203
+ summary: This gem provides a driver module for unobtainium allowing for more easily
204
+ waiting for (one of) multiple elements to change state.
205
+ test_files:
206
+ - spec/data/foo.html
207
+ - spec/module_spec.rb
208
+ - spec/spec_helper.rb
209
+ has_rdoc: