Class: Driver

Inherits:
Object
  • Object
show all
Defined in:
lib/driver.rb

Constant Summary collapse

@@driver =
nil
@@s3 =
nil

Class Method Summary collapse

Class Method Details

._log_shartObject



75
76
77
78
79
80
81
82
83
84
# File 'lib/driver.rb', line 75

def self._log_shart
  #squeeze out the logs between each selenium call
  unless Gridium.config.selenium_log_level == 'OFF'
  @@driver.manage.logs.available_types.each {|log_type|
    @@driver.manage.logs.get(log_type).each {|log_statement|
      Log.debug("[SELENIUM::LOGS::#{log_type.upcase}] #{log_statement}")
    }
  }
  end
end

._set_capabilitiesObject



86
87
88
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
# File 'lib/driver.rb', line 86

def self._set_capabilities()
  log_level = Gridium.config.selenium_log_level
  Selenium::WebDriver::Remote::Capabilities.new(
    browser_name: Gridium.config.browser,
    # log all the things
    loggingPrefs: {
      :browser => log_level,
      :client => log_level,
      :driver => log_level,
      :server => log_level
    },
    chrome_options: {
      args: ['--start-maximized', '--privileged', '--disable-web-security'],
      prefs: {
        # Need configurable download directory. Currently not supported on Selenium Grid
        download: {
          prompt_for_download: false,
          directory_upgrade: true,
          default_directory: Dir.pwd,
          extensions_to_open: ""
        },
        save_file: {
          default_directory: Dir.pwd
        },
        credentials_enable_service: false
      }
    }
  )
end


343
344
345
346
# File 'lib/driver.rb', line 343

def self.add_cookie(cookie)
  Log.debug("[Gridium::Driver] Adding cookie named #{cookie[:name]}")
  Driver.driver.manage.add_cookie(cookie)
end

.all_cookiesObject



358
359
360
361
# File 'lib/driver.rb', line 358

def self.all_cookies
  Log.debug("[Gridium::Driver] Getting all cookies")
  Driver.driver.manage.all_cookies
end

.close_windowObject



296
297
298
299
# File 'lib/driver.rb', line 296

def self.close_window
  Log.debug("[Gridium::Driver] Closing window (#{driver.title})...")
  DriverExtensions.close_window
end

.current_domainObject



198
199
200
201
202
203
204
205
206
207
208
209
# File 'lib/driver.rb', line 198

def self.current_domain
  site_url = driver.current_url.to_s
  # domain = site_url.match(/(https?:\/\/)?(\S*\.)?([\w\d]*\.\w+)\/?/i)[3]
  domain = URI.parse(site_url)
  host = domain.host
  if (!host.nil?)
    Log.debug("[Gridium::Driver] Current domain is: (#{host}).")
    return host
  else
    Log.error("[Gridium::Driver] Unable to parse URL.")
  end
end

.current_urlObject



189
190
191
# File 'lib/driver.rb', line 189

def self.current_url
  driver.current_url
end

.delete_all_cookiesObject



363
364
365
366
# File 'lib/driver.rb', line 363

def self.delete_all_cookies
  Log.debug("[Gridium::Driver] Deleting all cookies")
  Driver.driver.manage.delete_all_cookies
end


348
349
350
351
# File 'lib/driver.rb', line 348

def self.delete_cookie(cookie_name)
  Log.debug("[Gridium::Driver] Deleting cookie named #{cookie_name}")
  Driver.driver.manage.delete_cookie(cookie_name)
end

.driverObject



45
46
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
72
73
# File 'lib/driver.rb', line 45

def self.driver
  unless @@driver
    Log.debug("[Gridium::Driver]  Driver.driver: instantiating new driver")
    @browser_type = Gridium.config.browser
    ##Adding support for remote browsers
    if Gridium.config.browser_source == :remote
      @@driver = Selenium::WebDriver.for(:remote, url: Gridium.config.target_environment, desired_capabilities: _set_capabilities)
      Log.debug("[Gridium::Driver] Remote Browser Requested: #{@@driver}")

      #this file detector is only used for remote drivers and is needed to upload files from test_host through Grid to browser
      @@driver.file_detector = lambda do |args|
        str = args.first.to_s
        str if File.exist?(str)
      end
    else
      @@driver = Selenium::WebDriver.for(Gridium.config.browser, desired_capabilities: _set_capabilities)
    end

    reset
  end

  _log_shart #push out logs before doing something with selenium
  @@driver
rescue StandardError => e
  Log.debug("[Gridium::Driver] #{e.backtrace.inspect}")
  Log.info("[Gridium::Driver] Driver did not load within (#{Gridium.config.page_load_timeout}) seconds.  [#{e.message}]")
  $fail_test_instantly = true
  Kernel.fail(e.message)
end

.driver=(driver) ⇒ Object



116
117
118
119
# File 'lib/driver.rb', line 116

def self.driver= driver
  @@driver.quit if @@driver
  @@driver = driver
end

.evaluate_script(script) ⇒ Object



252
253
254
# File 'lib/driver.rb', line 252

def self.evaluate_script(script)
  driver.execute_script "return #{script}"
end

.execute_script(script, element) ⇒ Object

Execute Javascript on the element

Parameters:

  • script (String)
    • Javascript source to execute

  • element (Element)

Returns:

  • The value returned from the script



231
232
233
234
235
236
237
238
239
# File 'lib/driver.rb', line 231

def self.execute_script(script, element)
  if element.is_a?(Element)
    #we dont care if Gridium.config.visible_elements_only is set to true or not
    ele = driver.find_element(element.by, element.locator)
    driver.execute_script(script, ele)
  else
    driver.execute_script(script, element)
  end
end

.execute_script_driver(script) ⇒ Object

Execute Javascript on the page

Parameters:

  • script (String)
    • Javascript source to execute

Returns:

  • The value returned from the script



248
249
250
# File 'lib/driver.rb', line 248

def self.execute_script_driver(script)
  driver.execute_script(script)
end


353
354
355
356
# File 'lib/driver.rb', line 353

def self.get_cookie(cookie_name)
  Log.debug("[Gridium::Driver] Getting cookie named #{cookie_name}")
  Driver.driver.manage.cookie_named(cookie_name)
end

.go_backObject



173
174
175
# File 'lib/driver.rb', line 173

def self.go_back
  driver.navigate.back
end

.go_forwardObject



177
178
179
# File 'lib/driver.rb', line 177

def self.go_forward
  driver.navigate.forward
end

.htmlObject



181
182
183
# File 'lib/driver.rb', line 181

def self.html
  driver.page_source
end

.list_open_windowsObject



281
282
283
284
285
286
287
288
289
# File 'lib/driver.rb', line 281

def self.list_open_windows
  handles = driver.window_handles
  Log.debug("[Gridium::Driver] List of active windows:")
  handles.each do |handle|
    driver.switch_to.window(handle)
    Log.debug("[Gridium::Driver]  Window with title: (#{driver.title}) and handle: #{handle} is currently open.")
  end
  driver.switch_to.window(driver.window_handles.first)
end


153
154
155
156
# File 'lib/driver.rb', line 153

def self.nav(path)
  Log.debug("[Gridium::Driver] Driver.nav: #{@@driver}")
  visit(Gridium.config.url + path)
end

.open_new_window(url) ⇒ Object



291
292
293
294
# File 'lib/driver.rb', line 291

def self.open_new_window(url)
  Log.debug("[Gridium::Driver] Opening new window and loading url (#{url})...")
  DriverExtensions.open_new_window(url)
end

.quitObject



158
159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/driver.rb', line 158

def self.quit
  if @@driver
    begin
      _log_shart #push out the last logs
      Log.debug('[Gridium::Driver] Shutting down web driver...')
      @@driver.quit
    rescue Selenium::WebDriver::Error::NoSuchDriverError => e
      Log.debug("[Gridium::Driver] #{e.backtrace.inspect}")
      Log.error("[Gridium::Driver] Failed to shutdown webdriver: #{e.message}")
    ensure
      @@driver = nil
    end
  end
end

.refreshObject



193
194
195
# File 'lib/driver.rb', line 193

def self.refresh
  driver.navigate.refresh
end

.resetObject



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/driver.rb', line 9

def self.reset
  Log.debug("[Gridium::Driver] Driver.reset: #{@@driver}")
  driver.manage.delete_all_cookies
  driver.manage.timeouts.page_load = Gridium.config.page_load_timeout
  driver.manage.timeouts.implicit_wait = 0 # always use explicit waits!

  # Ensure the browser is maximized to maximize visibility of element
  # Currently doesn't work with chromedriver, but the following workaround does:
  if @browser_type.eql?(:chrome)
    driver.manage.window.move_to(0, 0)
    width = driver.execute_script("return screen.width;")
    height = driver.execute_script("return screen.height;")
    driver.manage.window.resize_to(width, height)
    driver.manage.window.move_to(0, 0)
  else
    driver.manage.window.maximize
  end
end

.s3Object



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/driver.rb', line 28

def self.s3
  unless @@s3
    if Gridium.config.screenshots_to_s3
      #do stuff
      s3_project_folder = Gridium.config.project_name_for_s3
      s3_subfolder = Gridium.config.subdirectory_name_for_s3
      Log.debug("[Gridium::Driver] configuring s3 to save files to this directory: #{s3_project_folder} in addition to being saved locally")
      @@s3 = Gridium::GridiumS3.new(s3_project_folder, s3_subfolder)
      Log.debug("[Gridium::Driver] s3 is #{@@s3}")
    else
      Log.debug("[Gridium::Driver] s3 screenshots not enabled in spec_helper; they will be only be saved locally")
    end
  end

  @@s3
end

.save_screenshot(type = 'saved') ⇒ String

Saves the screenshot of browser to local disk. Uploads if S3, if configured

Returns:

  • (String)

    screenshot_path - Local path, or S3 url



260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
# File 'lib/driver.rb', line 260

def self.save_screenshot(type = 'saved')
  Log.debug ("[Gridium::Driver] Capturing screenshot of browser...")
  timestamp = Time.now.strftime("%Y_%m_%d__%H_%M_%S")
  filename = "screenshot__#{timestamp}__#{type}.png"
  screenshot_path = local_path = File.join($current_run_dir, filename)

  # Save screenshot locally
  driver.save_screenshot(local_path)
  Log.info("[Gridium::Driver] screenshot saved to #{local_path}")

  # Push the screenshot up to S3?
  if Gridium.config.screenshots_to_s3
    screenshot_path = s3.save_file(local_path)
    Log.info("[Gridium::Driver] #{filename} uploaded to S3 at '#{screenshot_path}'")
  end

  SpecData.screenshots_captured.push filename   # used by custom_formatter.rb for embedding in report

  screenshot_path
end

.send_keys(*args) ⇒ Object

Raw driver send_keys to element, or to current active element first arg may be an optional element, otherwise send the requested keys

Parameters:

  • args (Array)


371
372
373
# File 'lib/driver.rb', line 371

def self.send_keys(*args)
  Driver.driver.action.send_keys(*args).perform
end

.switch_to_frame(by, locator) ⇒ Object



331
332
333
334
335
# File 'lib/driver.rb', line 331

def self.switch_to_frame(by, locator)
  Log.debug("[Gridium::Driver] Attempting to switch to Frame at: #{locator}")
  driver.switch_to.frame(driver.find_element(by, locator))
  Log.debug("[Gridium::Driver] Frame at: #{locator} is now active frame!")
end

.switch_to_main_windowObject



324
325
326
327
328
329
# File 'lib/driver.rb', line 324

def self.switch_to_main_window
  current_title = driver.title
  Log.debug("[Gridium::Driver] Current window is: (#{current_title}).  Switching to main window...")
  driver.switch_to.window(driver.window_handles.first)
  Log.debug("[Gridium::Driver] Window (#{driver.title}) is now the active window.")
end

.switch_to_next_windowObject



317
318
319
320
321
322
# File 'lib/driver.rb', line 317

def self.switch_to_next_window
  current_title = driver.title
  Log.debug("[Gridium::Driver] Current window is: (#{current_title}).  Switching to next window...")
  driver.switch_to.window(driver.window_handles.last)
  Log.debug("[Gridium::Driver] Window (#{driver.title}) is now the active window.")
end

.switch_to_parent_frameObject



337
338
339
340
341
# File 'lib/driver.rb', line 337

def self.switch_to_parent_frame
  Log.debug("[Gridium::Driver] Switching back to main parent frame")
  driver.switch_to.parent_frame
  Log.debug("[Gridium::Driver] Now back to Parent Frame")
end

.switch_to_window(title) ⇒ Object



301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
# File 'lib/driver.rb', line 301

def self.switch_to_window(title)
  current_title = driver.title
  Log.debug("[Gridium::Driver] Current window is: (#{current_title}).  Switching to next window (#{title})...")
  handles = driver.window_handles
  driver.switch_to.window(handles.first)
  handles.each do |handle|
    driver.switch_to.window(handle)
    if driver.title == title
      Log.debug("[Gridium::Driver] Window (#{driver.title}) is now the active window.")
      return
    end
  end
  list_open_windows
  Log.error("[Gridium::Driver] Unable to switch to window with title (#{title}).")
end

.titleObject



185
186
187
# File 'lib/driver.rb', line 185

def self.title
  driver.title
end

.verify_url(given_url) ⇒ Object



211
212
213
214
215
216
217
218
219
220
221
# File 'lib/driver.rb', line 211

def self.verify_url(given_url)
  Log.debug('[Gridium::Driver] Verifying URL...')
  current_url = self.current_url.to_s

  if current_url.include?(given_url)
    Log.debug("[Gridium::Driver] Confirmed. (#{current_url}) includes (#{given_url}).")
    $verification_passes += 1
  else
    Log.error("[Gridium::Driver] (#{current_url}) does not include (#{given_url}).")
  end
end

.visit(path) ⇒ Object

#

Driver Commands #

#


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
# File 'lib/driver.rb', line 125

def self.visit(path)
  Log.debug("[Gridium::Driver]  Driver.Visit: #{@@driver}")
  retries = Gridium.config.page_load_retries

  begin
    if path
      Log.debug("[Gridium::Driver] Navigating to url: (#{path}).")
      driver
      time_start = Time.now
      driver.navigate.to(path)
      time_end = Time.new
      page_load = (time_end - time_start)
      Log.debug("[Gridium::Driver] Page loaded in (#{page_load}) seconds.")
      $verification_passes += 1
    end
  rescue StandardError => e
    Log.debug("[Gridium::Driver] #{e.backtrace.inspect}")
    Log.error("[Gridium::Driver] Timed out attempting to load #{path} for #{Gridium.config.page_load_timeout} seconds:\n#{e.message}\n - Also be sure to check the url formatting.  http:// is required for proper test execution (www is optional).")
    if retries > 0
      Log.info("[Gridium::Driver] Retrying page load of #{path}")
      retries -= 1
      retry
    end

    raise e
  end
end