Class: Selenium::WebDriver::Remote::Bridge

Inherits:
Object
  • Object
show all
Defined in:
lib/angular_webdriver/protractor/webdriver_patch.rb

Defined Under Namespace

Classes: WrappedParent

Constant Summary collapse

FIND_ELEMENT_METHODS =
[:findElement, :findChildElement].freeze
FIND_ELEMENTS_METHODS =
[:findElements, :findChildElements].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#protractorObject

Returns the value of attribute protractor.



64
65
66
# File 'lib/angular_webdriver/protractor/webdriver_patch.rb', line 64

def protractor
  @protractor
end

Instance Method Details

#driver_get(url) ⇒ Object

driver.get uses execute which invokes protractor.get protractor.get needs to call driver.get without invoking protractor.get.

this is accomplished by using driver_get and raw_execute



205
206
207
# File 'lib/angular_webdriver/protractor/webdriver_patch.rb', line 205

def driver_get(url)
  raw_execute(:get, {}, :url => url)['value']
end

#execute(*args) ⇒ Object

executes a command on the remote server.

Returns the ‘value’ of the returned payload



219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
# File 'lib/angular_webdriver/protractor/webdriver_patch.rb', line 219

def execute(*args)
  raise 'Must initialize protractor' unless protractor
  method_symbol = args.first
  unless protractor.ignore_sync
    # override get method which has special sync logic
    # (not handled via sync method)
    if method_symbol == :get
      url = args.last[:url]
      return protractor.get url
    end

    protractor.sync method_symbol
  end

  timeout            = max_wait_seconds
  finder             = lambda { raw_execute(*args)['value'] }
  find_one_element   = FIND_ELEMENT_METHODS.include?(method_symbol)
  find_many_elements = FIND_ELEMENTS_METHODS.include?(method_symbol)

  if find_one_element
    wait(timeout: timeout, bubble: true) do
      finder.call
    end
  elsif find_many_elements
    result = []

    # Ignore any exceptions here because find_elements returns
    # an empty array when there are no values found, not an error.
    ignore do
      wait_true(timeout) do
        result = finder.call
        result.length > 0
      end
    end

    result ||= []
    result
  else # all other commands
    finder.call
  end
end

#find_element_by(how, what, parent = nil) ⇒ Object



169
170
171
172
173
174
175
176
177
178
179
180
181
# File 'lib/angular_webdriver/protractor/webdriver_patch.rb', line 169

def find_element_by(how, what, parent = nil)
  if protractor.finder? how
    return protractor_find(false, how, what, parent)
  end

  if parent
    id = execute :findChildElement, { :id => parent }, { :using => how, :value => what }
  else
    id = execute :findElement, {}, { :using => how, :value => what }
  end

  Element.new self, element_id_from(id)
end

#find_elements_by(how, what, parent = nil) ⇒ Object



183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/angular_webdriver/protractor/webdriver_patch.rb', line 183

def find_elements_by(how, what, parent = nil)
  if protractor.finder? how
    return protractor_find(true, how, what, parent)
  end

  if parent
    ids = execute :findChildElements, { :id => parent }, { :using => how, :value => what }
  else
    ids = execute :findElements, {}, { :using => how, :value => what }
  end

  ids.map { |id| Element.new self, element_id_from(id) }
end

#max_wait_secondsObject



72
73
74
75
# File 'lib/angular_webdriver/protractor/webdriver_patch.rb', line 72

def max_wait_seconds
  # default to 0
  @max_wait_seconds ||= 0
end

#protractor_find(many, how, what, parent = nil) ⇒ Object



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/angular_webdriver/protractor/webdriver_patch.rb', line 89

def protractor_find(many, how, what, parent = nil)
  timeout = max_wait_seconds

  # we have to waitForAngular here. unlike selenium locators,
  # protractor locators don't go through execute. execute uses
  # protractor.sync to run waitForAngular when finding elements.
  wait(timeout: timeout, bubble: true) { protractor.waitForAngular }

  # execute_script will invoke to_json on the parent, WrappedParent
  # ensures that the JSON produces the expected result.
  using         = parent ? WrappedParent.new(parent) : false
  root_selector = protractor.root_element
  comment       = "Protractor find by.#{how}"

  # args order from locators.js
  case how
    when 'binding', 'exactBinding'
      exact              = how == 'exactBinding'
      binding_descriptor = what
      args               = [binding_descriptor, exact, using, root_selector]
      protractor_js      = protractor.client_side_scripts.find_bindings
    when 'partialButtonText'
      search_text   = what
      args          = [search_text, using, root_selector]
      protractor_js = protractor.client_side_scripts.find_by_partial_button_text
    when 'buttonText'
      search_text   = what
      args          = [search_text, using, root_selector]
      protractor_js = protractor.client_side_scripts.find_by_button_text
    when 'model'
      model         = what
      args          = [model, using, root_selector]
      protractor_js = protractor.client_side_scripts.find_by_model
    when 'options'
      options_descriptor = what
      args               = [options_descriptor, using, root_selector]
      protractor_js      = protractor.client_side_scripts.find_by_options
    when 'cssContainingText'
      json          = JSON.parse what
      css_selector  = json['cssSelector']
      search_text   = json['searchText']
      args          = [css_selector, search_text, using, root_selector]
      protractor_js = protractor.client_side_scripts.find_by_css_containing_text
    when 'repeater' # includes 'exactRepeater'
      json          = JSON.parse what
      repeater_args = json['args'].values # json args is a hash
      # using and root_selector are always passed to repeater even
      # if the script doesn't use them.
      args          = repeater_args + [using, root_selector]

      # findRepeaterElement, findRepeaterRows, findRepeaterColumn, findAllRepeaterRows
      script_name   = json['script'].intern

      protractor_js = protractor.client_side_scripts.scripts[script_name]
  end

  finder = lambda { protractor.executeScript_(protractor_js, comment, *args) }

  result = []

  # Ignore any exceptions here because find_elements returns
  # an empty array when there are no values found, not an error.
  ignore do
    wait_true(timeout) do
      result = finder.call
      result.length > 0
    end
  end

  result ||= []

  if many
    return result
  else
    result = result.first
    return result if result
    fail ::Selenium::WebDriver::Error::NoSuchElementError
  end
end

#set_max_wait(value) ⇒ Object



66
67
68
69
70
# File 'lib/angular_webdriver/protractor/webdriver_patch.rb', line 66

def set_max_wait value
  fail 'set_max_wait value must be a number' unless value.is_a?(Numeric)
  # ensure no negative values
  @max_wait_seconds = value >= 0 ? value : 0
end