Class: Unobtainium::Driver
- Inherits:
-
Object
- Object
- Unobtainium::Driver
- Defined in:
- lib/unobtainium/driver.rb
Overview
Creating a Driver instance creates either an Appium or Selenium driver depending on the arguments, and delegates all else to the underlying implementation.
It’s possible to add more drivers, but Appium and Selenium are the main targets.
Instance Attribute Summary collapse
-
#impl ⇒ Object
readonly
The driver implementation itself; do not use this unless you have to.
-
#label ⇒ Symbol
readonly
The normalized label for the driver implementation.
-
#options ⇒ Hash
readonly
The options hash the driver implementation is using.
Class Method Summary collapse
-
.create(label, opts = nil) ⇒ Object
Create a driver instance with the given arguments.
-
.get_driver(label) ⇒ Object
private
Out of the loaded drivers, returns the one matching the label (if any).
-
.load_drivers ⇒ Object
private
Load drivers; this loads all driver implementations included in this gem.
-
.register_implementation(klass, path) ⇒ Object
Add a new driver implementation.
-
.register_module(klass, path) ⇒ Object
Add a new driver module.
-
.resolve_options(label, opts = nil) ⇒ Object
private
Resolves everything to do with driver options:.
Instance Method Summary collapse
-
#method_missing(meth, *args, &block) ⇒ Object
Map any missing method to the driver implementation.
-
#respond_to_missing?(meth, include_private = false) ⇒ Boolean
Map any missing method to the driver implementation.
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(meth, *args, &block) ⇒ Object
Map any missing method to the driver implementation
222 223 224 225 226 227 228 229 |
# File 'lib/unobtainium/driver.rb', line 222 def method_missing(meth, *args, &block) if not @impl.nil? and @impl.respond_to?(meth) return @impl.send(meth.to_s, *args, &block) end # :nocov: return super # :nocov: end |
Instance Attribute Details
#impl ⇒ Object (readonly)
Returns the driver implementation itself; do not use this unless you have to.
209 210 211 |
# File 'lib/unobtainium/driver.rb', line 209 def impl @impl end |
#label ⇒ Symbol (readonly)
Returns the normalized label for the driver implementation.
202 203 204 |
# File 'lib/unobtainium/driver.rb', line 202 def label @label end |
#options ⇒ Hash (readonly)
Returns the options hash the driver implementation is using.
205 206 207 |
# File 'lib/unobtainium/driver.rb', line 205 def @options end |
Class Method Details
.create(label, opts = nil) ⇒ Object
Create a driver instance with the given arguments.
30 31 32 |
# File 'lib/unobtainium/driver.rb', line 30 def create(label, opts = nil) new(label, opts) end |
.get_driver(label) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Out of the loaded drivers, returns the one matching the label (if any).
186 187 188 189 190 191 192 193 194 195 |
# File 'lib/unobtainium/driver.rb', line 186 def get_driver(label) # Of all the loaded classes, choose the first (unsorted) to match the # requested driver label @@drivers.keys.each do |klass| if klass.matches?(label) return klass end end return nil end |
.load_drivers ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Load drivers; this loads all driver implementations included in this gem. You can register external implementations with the :register_implementation method.
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 |
# File 'lib/unobtainium/driver.rb', line 156 def load_drivers pattern = File.join(File.dirname(__FILE__), 'drivers', '*.rb') Dir.glob(pattern).each do |fpath| # Determine class name from file name fname = File.basename(fpath, '.rb') fname = fname.split('_').map(&:capitalize).join begin require fpath klassname = 'Unobtainium::Drivers::' + fname klass = Object.const_get(klassname) Driver.register_implementation(klass, fpath) rescue LoadError => err # :nocov: raise LoadError, "#{err.}: unknown problem loading driver, "\ "aborting!" # :nocov: rescue NameError => err # :nocov: raise LoadError, "#{err.}: unknown problem loading driver, "\ "aborting!" # :nocov: end end end |
.register_implementation(klass, path) ⇒ Object
Add a new driver implementation. The first parameter is the class itself, the second should be a file path pointing to the file where the class is defined. You would typically pass ‘__FILE__` for the second parameter.
Using file names lets us figure out whether the class is a duplicate, or merely a second registration of the same class.
Driver classes must implement the class methods listed in ‘DRIVER_METHODS`.
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/unobtainium/driver.rb', line 47 def register_implementation(klass, path) # We need to deal with absolute paths only fpath = File.absolute_path(path) # Figure out if the class implements all the methods we need; we're not # checking for anything else. klass_methods = klass.methods - klass.instance_methods - Object.methods if DRIVER_METHODS - klass_methods != [] raise LoadError, "Driver #{klass.name} is not implementing all of "\ "the class methods #{DRIVER_METHODS}, aborting!" end # The second question is whether the same class is already known, or # whether a class with the same name but under a different location is # known. if @@drivers.include?(klass) and @@drivers[klass] != fpath raise LoadError, "Driver #{klass.name} is duplicated in file "\ "'#{fpath}'; previous definition is here: "\ "'#{@@drivers[klass]}'" end # If all of that was ok, we can register the implementation. @@drivers[klass] = fpath end |
.register_module(klass, path) ⇒ Object
Add a new driver module. The first parameter is the class itself, the second should be a file path pointing to the file where the class is defined. You would typically pass ‘__FILE__` for the second parameter.
Driver modules must implement the class methods listed in ‘MODULE_METHODS`.
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/unobtainium/driver.rb', line 82 def register_module(klass, path) # We need to deal with absolute paths only fpath = File.absolute_path(path) # Figure out if the class implements all the methods we need; we're not # checking for anything else. klass_methods = klass.methods - klass.instance_methods - Object.methods if MODULE_METHODS - klass_methods != [] raise LoadError, "Driver module #{klass.name} is not implementing all "\ "of the class methods #{MODULE_METHODS}, aborting!" end # The second question is whether the same class is already known, or # whether a class with the same name but under a different location is # known. if @@modules.include?(klass) and @@modules[klass] != fpath raise LoadError, "Driver module #{klass.name} is duplicated in file "\ "'#{fpath}'; previous definition is here: "\ "'#{@@modules[klass]}'" end # If all of that was ok, we can register the implementation. @@modules[klass] = fpath end |
.resolve_options(label, opts = nil) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Resolves everything to do with driver options:
-
Normalizes the label
-
Loads the driver class
-
Normalizes and extends options from the driver implementation
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/unobtainium/driver.rb', line 120 def (label, opts = nil) if label.nil? or label.empty? raise ArgumentError, "Need at least one argument specifying the driver!" end label = label.to_sym if not opts.nil? if not opts.is_a? Hash raise ArgumentError, "The second argument is expected to be an "\ "options Hash!" end end # Get the driver class. load_drivers driver_klass = get_driver(label) if not driver_klass raise LoadError, "No driver implementation matching #{label} found, "\ "aborting!" end # Sanitize options according to the driver's idea = opts if driver_klass.respond_to?(:resolve_options) label, = driver_klass.(label, opts) end return label, , driver_klass end |
Instance Method Details
#respond_to_missing?(meth, include_private = false) ⇒ Boolean
Map any missing method to the driver implementation
213 214 215 216 217 218 |
# File 'lib/unobtainium/driver.rb', line 213 def respond_to_missing?(meth, include_private = false) if not @impl.nil? and @impl.respond_to?(meth, include_private) return true end return super end |