class RUTL::View
Base view class. It's used to call the magical method_messing stuff to parse the view object files into actual objects.
Attributes
Written by Application
and only used internally.
Public Class Methods
rubocop:enable Style/ClassVars
# File lib/rutl/view.rb, line 43 def initialize(interface) @interface = interface # Dirty trick because we're loading all of view classes from files and # then initializing them, calling their layout methods to do magic. # The view class knows what views are loaded. return if @@loaded_views.include?(self.class) layout @@loaded_views << self.class end
BUGBUG #1: Some view in a generic app should not have URL.
BUGBUG: Kludgy. What do I really want to do here? Make it easy to define a view's default url and also matchers for view urls for views with variable urls? rubocop:disable Style/TrivialAccessors
# File lib/rutl/view.rb, line 17 def self.url @url end
Public Instance Methods
rubocop:enable Style/TrivialAccessors
# File lib/rutl/view.rb, line 26 def go_to_here # Ovveride this in base view to have something more # complicated than this. @interface.driver.navigate.to(url) end
# File lib/rutl/view.rb, line 32 def loaded? # Default to only checking url to see if view loaded. url == @interface.driver.current_url end
This creates a new element instance whenever it's called. Because of that we can't keep state in any element objects. That seems like a good thing, actually. Called by layout method on views.
Hard to make shorter. rubocop:disable Metrics/MethodLength
# File lib/rutl/view.rb, line 93 def method_missing(element, *args, &_block) name, selectors, rest = args context = RUTL::Element::ElementContext.new(destinations: rest, interface: @interface, selectors: selectors) case element when /button/, /checkbox/, /element/, /link/ add_method(name: name, context: context, klass: element) when /text/ add_method(name: name, context: context, klass: element) add_method(name: name, context: context, klass: element, setter: true) else # TODO: replace with a super call. This is useful for debugging for now. raise "#{element} NOT FOUND WITH ARGS #{args}!!!" end end
rubocop:enable Metrics/MethodLength
# File lib/rutl/view.rb, line 111 def respond_to_missing?(*args) # Is this right at all??? case args[0].to_s when /button/, /checkbox/, /element/, /link/, /text/, 'driver', 'children', 'loaded?' true when 'ok_link' raise 'OK LINK WAY DOWN HERE IN BASE VIEW!!!' else # I think it's good to raise but change the message. raise 'TODO: BETTER ERROR MESSAGE, PLEASE. I AM SHOUTING!!!\n' \ 'Drew, you hit this most often when checking current view ' \ "rather than current view class:\n\n #{args}" # I think I want to raise instead of returningn false. end end
# File lib/rutl/view.rb, line 21 def url self.class.url end
Private Instance Methods
Dynamically add a method, :<name> (or :<name>= if setter) to the current class where that method creates an instance of klass. context is a RUTL::Element::ElementContext
As it is, this seems silly to break into pieces for Rubocop. rubocop:disable Metrics/MethodLength
# File lib/rutl/view.rb, line 68 def add_method(context:, klass:, name:, setter: false) name = "#{name}_#{klass.downcase}" if RUTL::HUNGARIAN constant = Module.const_get("RUTL::Element::#{klass.capitalize}") self.class.class_exec do if setter define_method("#{name}=") do |value| constant.new(context, value) end else define_method(name) do constant.new(context) end end end end