unobtainium-multifind 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: b372724a026239958b189cca8eef2da19be56b32
4
+ data.tar.gz: 09e80f23d67eaa9038944a0d9b85eae6a04609c6
5
+ SHA512:
6
+ metadata.gz: c593de1984c2fd92e32379caf34104037fd249c7349c590c60df58042b349d5e67577977146ad1e85d4bd7e036e9a7d7b74897f6d49f3b92f93ae0729e10ad3d
7
+ data.tar.gz: 008eb7a5e629f1cf95113287c18f60d861af673e68bc17c4a00665d8eae0595cccc0542d30987e4563b33f7204f830d69c581795d1d850d0291e6eb77e5a5a43
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: 89d15fbb64d0d6ed4ecc68d5fe9482efdccd047eb5a6b0266434d683115b848c
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in unobtainium-multifind.gemspec
4
+ gemspec
5
+
6
+ gem "codeclimate-test-reporter", group: :test, require: nil
data/Gemfile.lock ADDED
@@ -0,0 +1,78 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ unobtainium-multifind (0.1.0)
5
+ unobtainium (~> 0.5)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ ast (2.2.0)
11
+ childprocess (0.5.9)
12
+ ffi (~> 1.0, >= 1.0.11)
13
+ codeclimate-test-reporter (0.5.0)
14
+ simplecov (>= 0.7.1, < 1.0.0)
15
+ diff-lcs (1.2.5)
16
+ docile (1.1.5)
17
+ ffi (1.9.10)
18
+ json (1.8.3)
19
+ parser (2.3.1.0)
20
+ ast (~> 2.2)
21
+ phantomjs (2.1.1.0)
22
+ powerpack (0.1.1)
23
+ rainbow (2.1.0)
24
+ rake (11.1.2)
25
+ rspec (3.4.0)
26
+ rspec-core (~> 3.4.0)
27
+ rspec-expectations (~> 3.4.0)
28
+ rspec-mocks (~> 3.4.0)
29
+ rspec-core (3.4.4)
30
+ rspec-support (~> 3.4.0)
31
+ rspec-expectations (3.4.0)
32
+ diff-lcs (>= 1.2.0, < 2.0)
33
+ rspec-support (~> 3.4.0)
34
+ rspec-mocks (3.4.1)
35
+ diff-lcs (>= 1.2.0, < 2.0)
36
+ rspec-support (~> 3.4.0)
37
+ rspec-support (3.4.1)
38
+ rubocop (0.39.0)
39
+ parser (>= 2.3.0.7, < 3.0)
40
+ powerpack (~> 0.1)
41
+ rainbow (>= 1.99.1, < 3.0)
42
+ ruby-progressbar (~> 1.7)
43
+ unicode-display_width (~> 1.0, >= 1.0.1)
44
+ ruby-progressbar (1.8.0)
45
+ rubyzip (1.2.0)
46
+ selenium-webdriver (2.53.0)
47
+ childprocess (~> 0.5)
48
+ rubyzip (~> 1.0)
49
+ websocket (~> 1.0)
50
+ simplecov (0.11.2)
51
+ docile (~> 1.1.0)
52
+ json (~> 1.8)
53
+ simplecov-html (~> 0.10.0)
54
+ simplecov-html (0.10.0)
55
+ sys-proctable (1.0.0)
56
+ unicode-display_width (1.0.5)
57
+ unobtainium (0.5.0)
58
+ sys-proctable (~> 1.0)
59
+ websocket (1.2.3)
60
+ yard (0.8.7.6)
61
+
62
+ PLATFORMS
63
+ ruby
64
+
65
+ DEPENDENCIES
66
+ bundler (~> 1.12)
67
+ codeclimate-test-reporter
68
+ phantomjs
69
+ rake (~> 11.1)
70
+ rspec (~> 3.4)
71
+ rubocop (~> 0.39)
72
+ selenium-webdriver
73
+ simplecov (~> 0.11)
74
+ unobtainium-multifind!
75
+ yard (~> 0.8)
76
+
77
+ BUNDLED WITH
78
+ 1.12.1
data/LICENSE ADDED
@@ -0,0 +1,30 @@
1
+ Copyright (c) Jens Finkhaeuser (http://finkhaeuser.de/) and other
2
+ unobtainium-multifind 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,27 @@
1
+ # unobtainium-multifind
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-multifind.svg)](https://badge.fury.io/rb/unobtainium-multifind)
7
+ [![Build status](https://travis-ci.org/jfinkhaeuser/unobtainium-multifind.svg?branch=master)](https://travis-ci.org/jfinkhaeuser/unobtainium-multifind)
8
+ [![Code Climate](https://codeclimate.com/github/jfinkhaeuser/unobtainium-multifind/badges/gpa.svg)](https://codeclimate.com/github/jfinkhaeuser/unobtainium-multifind)
9
+ [![Test Coverage](https://codeclimate.com/github/jfinkhaeuser/unobtainium-multifind/badges/coverage.svg)](https://codeclimate.com/github/jfinkhaeuser/unobtainium-multifind/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-multifind'
17
+
18
+ include Unobtainium::World
19
+
20
+ driver.navigate.to('http://finkhaeuser.de')
21
+
22
+ elems = driver.multifind({ xpath: '//some-element' },
23
+ { xpath: '//other-element' })
24
+
25
+ # Entries will be nil if nothing is found by this xpath
26
+ puts elems.length # => 2
27
+ ```
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,10 @@
1
+ # coding: utf-8
2
+ #
3
+ # unobtainium-multifind
4
+ # https://github.com/jfinkhaeuser/unobtainium-multifind
5
+ #
6
+ # Copyright (c) 2016 Jens Finkhaeuser and other unobtainium-multifind contributors.
7
+ # All rights reserved.
8
+ #
9
+
10
+ require 'unobtainium-multifind/multifind'
@@ -0,0 +1,160 @@
1
+ # coding: utf-8
2
+ #
3
+ # unobtainium-multifind
4
+ # https://github.com/jfinkhaeuser/unobtainium-multifind
5
+ #
6
+ # Copyright (c) 2016 Jens Finkhaeuser and other unobtainium-multifind contributors.
7
+ # All rights reserved.
8
+ #
9
+
10
+ require 'unobtainium'
11
+
12
+ module Unobtainium
13
+ ##
14
+ # MultiFind namespace
15
+ module MultiFind
16
+ ##
17
+ # Driver module implementing multi find functionality.
18
+ module DriverModule
19
+
20
+ ##
21
+ # Default options. This hash is also used to detect if any of the Hashes
22
+ # passed to #multifind is an options Hash; it is considered one if it
23
+ # contains any of the keys specified here.
24
+ DEFAULT_OPTIONS = {
25
+ # If true, raises on error instead of returning nil
26
+ raise_on_error: false,
27
+ # If true, returns the error object instead of nil
28
+ return_errors: false,
29
+ # If :all is specified, all results are returned.
30
+ # If :first is specified, the first non-error result is
31
+ # returned.
32
+ # If :last is specified, the last non-error result is
33
+ # returned.
34
+ find: :all,
35
+ }.freeze
36
+
37
+ class << self
38
+ ##
39
+ # Returns true if the implementation has `#find_element`, false
40
+ # otherwise.
41
+ def matches?(impl)
42
+ return impl.respond_to?(:find_element)
43
+ end
44
+ end # class << self
45
+
46
+ ##
47
+ # Current options for multifind
48
+ attr_accessor :multifind_options
49
+ @multifind_options = DEFAULT_OPTIONS
50
+
51
+ def multifind(*args)
52
+ # Parse options
53
+ options, selectors = multifind_parse_options(*args)
54
+
55
+ # Now find elements
56
+ results = []
57
+ selectors.each do |selector|
58
+ begin
59
+ results << find_element(selector)
60
+ rescue ::Selenium::WebDriver::Error::NoSuchElementError => err
61
+ if options[:raise_on_error]
62
+ raise
63
+ end
64
+ if options[:return_errors]
65
+ results << err
66
+ next
67
+ end
68
+ results << nil
69
+ end
70
+ end
71
+
72
+ # Filter results, if necessary
73
+ return multifind_filter_results(options, results)
74
+ end
75
+
76
+ alias find multifind
77
+
78
+ private
79
+
80
+ ##
81
+ # Distinguishes between option hashes and selectors by detecting Hash
82
+ # arguments with keys from DEFAULT_OPTIONS. Those are considered to be
83
+ # options, and merged with any preceding option hashes, where latter
84
+ # occurrences overwrite earlier ones.
85
+ def multifind_parse_options(*args)
86
+ # Sanity
87
+ if @multifind_options.nil?
88
+ @multifind_options = DEFAULT_OPTIONS
89
+ end
90
+
91
+ # Distinguish between options and selectors
92
+ options = {}
93
+ selectors = []
94
+ args.each do |arg|
95
+ # Let the underlying API handle all non-Hashes
96
+ if not arg.is_a?(Hash)
97
+ selectors << arg
98
+ next
99
+ end
100
+
101
+ # See if it contains any of the keys we care about
102
+ option_keys = DEFAULT_OPTIONS.keys
103
+ diff = option_keys - arg.keys
104
+ if diff != option_keys
105
+ options.merge!(arg)
106
+ next
107
+ end
108
+
109
+ selectors << arg
110
+ end
111
+ options = @multifind_options.merge(options)
112
+ options = DEFAULT_OPTIONS.merge(options)
113
+
114
+ # Ensure that the 'find' option contains correct
115
+ # values only.
116
+ if not [:all, :first, :last].include?(options[:find])
117
+ raise ArgumentError, ":find option must be one of :all, :first or "\
118
+ ":last, but is: #{options[:find]}"
119
+ end
120
+
121
+ return options, selectors
122
+ end
123
+
124
+ ##
125
+ # Filters results from multifind; this largely means honouring the
126
+ # :find option.
127
+ def multifind_filter_results(options, results)
128
+ # That was easy!
129
+ if options[:find] == :all
130
+ return results
131
+ end
132
+
133
+ # Filtering :first and :last is identical, except we go backwards
134
+ # through the results array for :last.
135
+ if options[:find] == :last
136
+ results.reverse!
137
+ end
138
+
139
+ # We now return the first non-nil, non-error result
140
+ results.each do |result|
141
+ if result.nil?
142
+ next
143
+ end
144
+ if result.is_a?(::Selenium::WebDriver::Error::NoSuchElementError)
145
+ next
146
+ end
147
+ return [result]
148
+ end
149
+
150
+ # If we're here then we have no results, but want :first
151
+ # or :last. An empty result is appropriate.
152
+ return []
153
+ end
154
+ end # module DriverModule
155
+ end # module MultiFind
156
+ end # module Unobtainium
157
+
158
+ ::Unobtainium::Driver.register_module(
159
+ ::Unobtainium::MultiFind::DriverModule,
160
+ __FILE__)
@@ -0,0 +1,14 @@
1
+ # coding: utf-8
2
+ #
3
+ # unobtainium-multifind
4
+ # https://github.com/jfinkhaeuser/unobtainium-multifind
5
+ #
6
+ # Copyright (c) 2016 Jens Finkhaeuser and other unobtainium-multifind contributors.
7
+ # All rights reserved.
8
+ #
9
+ module Unobtainium
10
+ module MultiFind
11
+ # The current release version
12
+ VERSION = "0.1.0".freeze
13
+ end # module MultiFind
14
+ end # module Unobtainium
@@ -0,0 +1,4 @@
1
+ <foo>
2
+ <bar>
3
+ <something>else</something>
4
+ <foo>
@@ -0,0 +1,216 @@
1
+ # coding: utf-8
2
+ #
3
+ # unobtainium-multifind
4
+ # https://github.com/jfinkhaeuser/unobtainium-multifind
5
+ #
6
+ # Copyright (c) 2016 Jens Finkhaeuser and other unobtainium-multifind 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::MultiFind::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-multifind'
30
+ end.to_not raise_error(LoadError)
31
+ end
32
+
33
+ it "exposes find methods" do
34
+ drv = @tester.driver(DRIVER)
35
+ expect(drv.respond_to?(:find)).to be_truthy
36
+ expect(drv.respond_to?(:multifind)).to be_truthy
37
+ end
38
+ end
39
+
40
+ describe "find functionality" do
41
+ it "can find a single element" do
42
+ drv = @tester.driver(DRIVER)
43
+ drv.navigate.to(TEST_URL)
44
+ elem = drv.find(xpath: '//foo/bar')
45
+ expect(elem).not_to be_nil
46
+ expect(elem).not_to be_empty
47
+ expect(elem.length).to eql 1
48
+ expect(elem[0]).not_to be_nil
49
+ end
50
+
51
+ it "can find multiple elements" do
52
+ drv = @tester.driver(DRIVER)
53
+ drv.navigate.to(TEST_URL)
54
+ # rubocop:disable Style/BracesAroundHashParameters
55
+ elem = drv.find({ xpath: '//foo/bar' },
56
+ { xpath: '//something' })
57
+ # rubocop:enable Style/BracesAroundHashParameters
58
+ expect(elem).not_to be_nil
59
+ expect(elem).not_to be_empty
60
+ expect(elem.length).to eql 2
61
+ expect(elem[0]).not_to be_nil
62
+ expect(elem[1]).not_to be_nil
63
+ end
64
+
65
+ it "returns nil for elements not found" do
66
+ drv = @tester.driver(DRIVER)
67
+ drv.navigate.to(TEST_URL)
68
+ # rubocop:disable Style/BracesAroundHashParameters
69
+ elem = drv.find({ xpath: '//does-not-exist' },
70
+ { xpath: '//foo' })
71
+ # rubocop:enable Style/BracesAroundHashParameters
72
+ expect(elem).not_to be_nil
73
+ expect(elem).not_to be_empty
74
+ expect(elem.length).to eql 2
75
+ expect(elem[0]).to be_nil
76
+ expect(elem[1]).not_to be_nil
77
+ end
78
+
79
+ it "can return only the first element" do
80
+ drv = @tester.driver(DRIVER)
81
+ drv.navigate.to(TEST_URL)
82
+
83
+ # rubocop:disable Style/BracesAroundHashParameters
84
+ elem = drv.find({ xpath: '//foo/bar' },
85
+ { xpath: '//something' },
86
+ { find: :first })
87
+ # rubocop:enable Style/BracesAroundHashParameters
88
+ expect(elem).not_to be_nil
89
+ expect(elem).not_to be_empty
90
+ expect(elem.length).to eql 1
91
+ expect(elem[0]).not_to be_nil
92
+ end
93
+
94
+ it "can return only the last element" do
95
+ drv = @tester.driver(DRIVER)
96
+ drv.navigate.to(TEST_URL)
97
+
98
+ # rubocop:disable Style/BracesAroundHashParameters
99
+ elem = drv.find({ xpath: '//foo/bar' },
100
+ { xpath: '//something' },
101
+ { find: :last })
102
+ # rubocop:enable Style/BracesAroundHashParameters
103
+ expect(elem).not_to be_nil
104
+ expect(elem).not_to be_empty
105
+ expect(elem.length).to eql 1
106
+ expect(elem[0]).not_to be_nil
107
+ end
108
+
109
+ it "can return only the last non-error element when nil is returned" do
110
+ drv = @tester.driver(DRIVER)
111
+ drv.navigate.to(TEST_URL)
112
+
113
+ # rubocop:disable Style/BracesAroundHashParameters
114
+ elem = drv.find({ xpath: '//foo/bar' },
115
+ { xpath: '//does-not-exist' },
116
+ { find: :last })
117
+ # rubocop:enable Style/BracesAroundHashParameters
118
+ expect(elem).not_to be_nil
119
+ expect(elem).not_to be_empty
120
+ expect(elem.length).to eql 1
121
+ expect(elem[0]).not_to be_nil
122
+ end
123
+
124
+ it "can return only the last non-error element when errors are returned" do
125
+ drv = @tester.driver(DRIVER)
126
+ drv.navigate.to(TEST_URL)
127
+
128
+ # rubocop:disable Style/BracesAroundHashParameters
129
+ elem = drv.find({ xpath: '//foo/bar' },
130
+ { xpath: '//does-not-exist' },
131
+ { find: :last, return_errors: true })
132
+ # rubocop:enable Style/BracesAroundHashParameters
133
+ expect(elem).not_to be_nil
134
+ expect(elem).not_to be_empty
135
+ expect(elem.length).to eql 1
136
+ expect(elem[0]).not_to be_nil
137
+ end
138
+
139
+ it "can return empty when no matches are found with :first" do
140
+ drv = @tester.driver(DRIVER)
141
+ drv.navigate.to(TEST_URL)
142
+
143
+ # rubocop:disable Style/BracesAroundHashParameters
144
+ elem = drv.find({ xpath: '//does-not-exist' },
145
+ { find: :first })
146
+ # rubocop:enable Style/BracesAroundHashParameters
147
+ expect(elem).not_to be_nil
148
+ expect(elem).to be_empty
149
+ end
150
+
151
+ it "passes non-hash arguments without touching them" do
152
+ drv = @tester.driver(DRIVER)
153
+ drv.navigate.to(TEST_URL)
154
+ expect do
155
+ drv.find(42) # not a valid selector for selenium
156
+ end.to raise_error
157
+ end
158
+ end
159
+
160
+ describe "find options" do
161
+ it "can throw on errors" do
162
+ drv = @tester.driver(DRIVER)
163
+ drv.navigate.to(TEST_URL)
164
+ # rubocop:disable Style/BracesAroundHashParameters
165
+ expect do
166
+ drv.find({ xpath: '//does-not-exist' },
167
+ { xpath: '//foo' },
168
+ { raise_on_error: true })
169
+ end.to raise_error(::Selenium::WebDriver::Error::NoSuchElementError)
170
+ # rubocop:enable Style/BracesAroundHashParameters
171
+ end
172
+
173
+ it "can return errors" do
174
+ drv = @tester.driver(DRIVER)
175
+ drv.navigate.to(TEST_URL)
176
+ # rubocop:disable Style/BracesAroundHashParameters
177
+ elems = drv.find({ xpath: '//does-not-exist' },
178
+ { xpath: '//foo' },
179
+ { return_errors: true })
180
+ # rubocop:enable Style/BracesAroundHashParameters
181
+ expect(elems).not_to be_nil
182
+ expect(elems).not_to be_empty
183
+ expect(elems.length).to eql 2
184
+ expect(elems[0]).not_to be_nil
185
+ expect(elems[1]).not_to be_nil
186
+ is_error = elems[0].is_a?(::Selenium::WebDriver::Error::NoSuchElementError)
187
+ expect(is_error).to be_truthy
188
+ end
189
+
190
+ it "can honour instance options" do
191
+ drv = @tester.driver(DRIVER)
192
+ drv.navigate.to(TEST_URL)
193
+ drv.multifind_options = { raise_on_error: true }
194
+ expect do
195
+ drv.find(xpath: '//does-not-exist')
196
+ end.to raise_error(::Selenium::WebDriver::Error::NoSuchElementError)
197
+ end
198
+
199
+ it "validates :find" do
200
+ drv = @tester.driver(DRIVER)
201
+ drv.navigate.to(TEST_URL)
202
+
203
+ # Good option
204
+ drv.multifind_options = { find: :all }
205
+ expect do
206
+ drv.find(xpath: '//foo')
207
+ end.not_to raise_error
208
+
209
+ # Bad option
210
+ drv.multifind_options = { find: :bad }
211
+ expect do
212
+ drv.find(xpath: '//foo')
213
+ end.to raise_error
214
+ end
215
+ end
216
+ 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-multifind
4
+ # https://github.com/jfinkhaeuser/unobtainium-multifind
5
+ #
6
+ # Copyright (c) 2016 Jens Finkhaeuser and other unobtainium-multifind 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-multifind/version'
13
+
14
+ # rubocop:disable Style/UnneededPercentQ, Style/ExtraSpacing
15
+ # rubocop:disable Style/SpaceAroundOperators
16
+ Gem::Specification.new do |spec|
17
+ spec.name = "unobtainium-multifind"
18
+ spec.version = Unobtainium::MultiFind::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
+ finding (one of) multiple elements.
24
+
25
+ It requires a driver implementing the Selenium API, specifically the
26
+ #find_element method.
27
+ )
28
+ spec.summary = %q(
29
+ This gem provides a driver module for unobtainium allowing for more easily
30
+ finding (one of) multiple elements.
31
+ )
32
+ spec.homepage = "https://github.com/jfinkhaeuser/unobtainium-multifind"
33
+ spec.license = "MITNFA"
34
+
35
+ spec.files = `git ls-files -z`.split("\x0")
36
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
37
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
38
+ spec.require_paths = ["lib"]
39
+
40
+ spec.required_ruby_version = '>= 2.0'
41
+
42
+ spec.requirements = "Unobtainium driver implementing the Selenium API"
43
+
44
+ spec.add_development_dependency "bundler", "~> 1.12"
45
+ spec.add_development_dependency "rubocop", "~> 0.39"
46
+ spec.add_development_dependency "rake", "~> 11.1"
47
+ spec.add_development_dependency "rspec", "~> 3.4"
48
+ spec.add_development_dependency "simplecov", "~> 0.11"
49
+ spec.add_development_dependency "yard", "~> 0.8"
50
+ spec.add_development_dependency "selenium-webdriver"
51
+ spec.add_development_dependency "phantomjs"
52
+
53
+ spec.add_dependency "unobtainium", "~> 0.5"
54
+ end
55
+ # rubocop:enable Style/SpaceAroundOperators
56
+ # rubocop:enable Style/UnneededPercentQ, Style/ExtraSpacing
metadata ADDED
@@ -0,0 +1,195 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: unobtainium-multifind
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-04 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
+ description: "\n This gem provides a driver module for unobtainium allowing for
140
+ more easily\n finding (one of) multiple elements.\n\n It requires a driver
141
+ implementing the Selenium API, specifically the\n #find_element method.\n "
142
+ email:
143
+ - jens@finkhaeuser.de
144
+ executables: []
145
+ extensions: []
146
+ extra_rdoc_files: []
147
+ files:
148
+ - ".codeclimate.yml"
149
+ - ".gitignore"
150
+ - ".rspec"
151
+ - ".rubocop.yml"
152
+ - ".travis.yml"
153
+ - Gemfile
154
+ - Gemfile.lock
155
+ - LICENSE
156
+ - README.md
157
+ - Rakefile
158
+ - lib/unobtainium-multifind.rb
159
+ - lib/unobtainium-multifind/multifind.rb
160
+ - lib/unobtainium-multifind/version.rb
161
+ - spec/data/foo.html
162
+ - spec/module_spec.rb
163
+ - spec/spec_helper.rb
164
+ - unobtainium-multifind.gemspec
165
+ homepage: https://github.com/jfinkhaeuser/unobtainium-multifind
166
+ licenses:
167
+ - MITNFA
168
+ metadata: {}
169
+ post_install_message:
170
+ rdoc_options: []
171
+ require_paths:
172
+ - lib
173
+ required_ruby_version: !ruby/object:Gem::Requirement
174
+ requirements:
175
+ - - ">="
176
+ - !ruby/object:Gem::Version
177
+ version: '2.0'
178
+ required_rubygems_version: !ruby/object:Gem::Requirement
179
+ requirements:
180
+ - - ">="
181
+ - !ruby/object:Gem::Version
182
+ version: '0'
183
+ requirements:
184
+ - Unobtainium driver implementing the Selenium API
185
+ rubyforge_project:
186
+ rubygems_version: 2.4.5.1
187
+ signing_key:
188
+ specification_version: 4
189
+ summary: This gem provides a driver module for unobtainium allowing for more easily
190
+ finding (one of) multiple elements.
191
+ test_files:
192
+ - spec/data/foo.html
193
+ - spec/module_spec.rb
194
+ - spec/spec_helper.rb
195
+ has_rdoc: