Class: Driver

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

Constant Summary collapse

@@driver =
nil

Class Method Summary collapse

Class Method Details

._log_shartObject



65
66
67
68
69
70
71
72
73
74
# File 'lib/driver.rb', line 65

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



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/driver.rb', line 76

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


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

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

.all_cookiesObject



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

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

.close_windowObject



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

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

.current_domainObject



193
194
195
196
197
198
199
200
201
202
203
204
# File 'lib/driver.rb', line 193

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



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

def self.current_url
  driver.current_url
end

.delete_all_cookiesObject



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

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


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

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

.driverObject



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/driver.rb', line 26

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
    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")
      @s3 = nil
    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



111
112
113
114
# File 'lib/driver.rb', line 111

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

.evaluate_script(script) ⇒ Object



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

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



226
227
228
229
230
231
232
233
234
# File 'lib/driver.rb', line 226

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



243
244
245
# File 'lib/driver.rb', line 243

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


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

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



168
169
170
# File 'lib/driver.rb', line 168

def self.go_back
  driver.navigate.back
end

.go_forwardObject



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

def self.go_forward
  driver.navigate.forward
end

.htmlObject



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

def self.html
  driver.page_source
end

.list_open_windowsObject



276
277
278
279
280
281
282
283
284
# File 'lib/driver.rb', line 276

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


148
149
150
151
# File 'lib/driver.rb', line 148

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

.open_new_window(url) ⇒ Object



286
287
288
289
# File 'lib/driver.rb', line 286

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

.quitObject



153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/driver.rb', line 153

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



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

def self.refresh
  driver.navigate.refresh
end

.resetObject



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

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)
    width = driver.execute_script("return screen.width;")
    height = driver.execute_script("return screen.height;")
    driver.manage.window.move_to(0, 0)
    driver.manage.window.resize_to(width, height)
  else
    driver.manage.window.maximize
  end
end

.s3Object



106
107
108
109
# File 'lib/driver.rb', line 106

def self.s3
  #TODO figure out why I can't just use attr_reader :s3
  @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



255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
# File 'lib/driver.rb', line 255

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)


366
367
368
# File 'lib/driver.rb', line 366

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

.switch_to_frame(by, locator) ⇒ Object



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

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



319
320
321
322
323
324
# File 'lib/driver.rb', line 319

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



312
313
314
315
316
317
# File 'lib/driver.rb', line 312

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



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

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



296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
# File 'lib/driver.rb', line 296

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



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

def self.title
  driver.title
end

.verify_url(given_url) ⇒ Object



206
207
208
209
210
211
212
213
214
215
216
# File 'lib/driver.rb', line 206

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 #

#


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

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