Class: FunFX::Flex::Element

Inherits:
Object
  • Object
show all
Defined in:
lib/funfx/flex/element.rb

Overview

Base class for all Flex proxy elements

Constant Summary collapse

MAX_TRIES =
10

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(flex_app, parent_locator, *locator_hashes) ⇒ Element

Returns a new instance of Element.



16
17
18
19
20
21
22
# File 'lib/funfx/flex/element.rb', line 16

def initialize(flex_app, parent_locator, *locator_hashes)
  @flex_app = flex_app
  
  @flex_locator  = build_flex_locator(parent_locator, locator_hashes)

  @tries = 0
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method_name, id) ⇒ Object (private)

TODO: Find a better way to look up children that:

  • Is a documented API

  • No method_missing

  • Doesn’t clash with properties

  • Is only available on elements that can contain other elements (Container?)



156
157
158
# File 'lib/funfx/flex/element.rb', line 156

def method_missing(method_name, id)
  Elements.const_get(shift_case(method_name)).new(@flex_app, @flex_locator, id)
end

Instance Attribute Details

#flex_appObject (readonly)

Returns the value of attribute flex_app.



14
15
16
# File 'lib/funfx/flex/element.rb', line 14

def flex_app
  @flex_app
end

#flex_locatorObject (readonly)

Returns the value of attribute flex_locator.



14
15
16
# File 'lib/funfx/flex/element.rb', line 14

def flex_locator
  @flex_locator
end

Instance Method Details

#fire_event(event_name, *args) ⇒ Object



24
25
26
27
28
29
30
# File 'lib/funfx/flex/element.rb', line 24

def fire_event(event_name, *args)
  flex_args = args.join("_ARG_SEP_");
  flex_invoke do
    @flex_app.fire_event(@flex_locator, event_name, flex_args)
  end
  sleep FunFX.fire_pause unless FunFX.fire_pause.nil?
end

#flex_invokeObject



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/funfx/flex/element.rb', line 53

def flex_invoke
  @tries += 1
  raw_value = yield
  if raw_value.nil?
    if @tries < MAX_TRIES
      sleep 0.1
      raw_value = yield
    else
      raise "Flex app is busy and seems to stay busy!"
    end
  end
  FunFX.debug "Passed after #{@tries} tries"
  @tries = 0

  raise_if_funfx_error(raw_value)
end

#get_property_value(property, ruby_type) ⇒ Object



32
33
34
35
36
37
# File 'lib/funfx/flex/element.rb', line 32

def get_property_value(property, ruby_type)
  raw_value = flex_invoke do
    @flex_app.get_property_value(@flex_locator, property)
  end        
  ruby_type.from_funfx_string(raw_value)
end

#get_tabular_property_value(property, ruby_type) ⇒ Object



39
40
41
42
43
44
# File 'lib/funfx/flex/element.rb', line 39

def get_tabular_property_value(property, ruby_type)
  raw_value = flex_invoke do
    @flex_app.get_tabular_property_value(@flex_locator, property)
  end
  ruby_type.from_funfx_string(raw_value)
end

#invoke_tabular_method(method_name, ruby_type, *args) ⇒ Object



46
47
48
49
50
51
# File 'lib/funfx/flex/element.rb', line 46

def invoke_tabular_method(method_name, ruby_type, *args)
  raw_value = flex_invoke do
    @flex_app.invoke_tabular_method(@flex_locator, method_name, *args)
  end
  ruby_type.from_funfx_string(raw_value)
end

#label_element(id) ⇒ Object

Hack to work around name clash for label. It can be a primitive property or a sub element



106
107
108
# File 'lib/funfx/flex/element.rb', line 106

def label_element(id)
  Elements::FlexLabel.new(@flex_app, @flex_locator, id)
end

#raise_if_funfx_error(result) ⇒ Object



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/funfx/flex/element.rb', line 70

def raise_if_funfx_error(result)
  if result =~ /^____FUNFX_ERROR:\n(.*)/m
    lines = $1.split("\n")
    message = lines[0]
    trace = lines[1..-1].map do |line|
      if line =~ /^\s+at (.+\(\))\[(.+)\]$/
        meth = $1
        file_line = $2.gsub(/\\/, '/')
      elsif
        line =~ /^\s+at (.+\(\))$/
        meth = $1
        file_line = "UNKNOWN"
      else
        puts "Result\n" + result.to_s
        raise "Unmatched line: #{line}"
      end
      "#{file_line}:in `#{meth}'"
    end
    e = FunFXError.new(message)
    begin
      raise e
    rescue => e
      e.backtrace.unshift(trace).flatten!
      raise e
    end
  else
    result
  end
end

#shift_case(str) ⇒ Object



100
101
102
# File 'lib/funfx/flex/element.rb', line 100

def shift_case(str)
  return "Flex" + str.to_s.gsub(/^[a-z]|[_][a-z]/) { |a| a.upcase}.delete("_")
end