webdriver-user-agent 7.5 → 7.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9260c1a33a202278f16eadeb8c2e3e925e28896eccf6aaf778bc127460e4dbd2
4
- data.tar.gz: 70e9b164502d0c04e60c8391e8c6b8164ea6259846cecbe29212353cbf3d45cd
3
+ metadata.gz: c8f285c93bdc6daea5d101e3a61b973a82c9e25152ec14fbd90223ea382cd4ab
4
+ data.tar.gz: ff356f5cf939d1ea35ec8197ec9ccbc455c203458729da220016f7d861961b20
5
5
  SHA512:
6
- metadata.gz: e81485d6bf53586daae8c220ce77a8795bf576744eb19e6f6a45951f2dfea4079faadbc86ef540a8a939af0d240c35d9b5c460a719d089453e40ee2102d74736
7
- data.tar.gz: 25524c3865c8a54ce01f3c62d46c214fa33b6f1475aea1f5321268ab5c003796f0d40a807efcd16e8198bef8b02f3cfbeffbcf909842cb12162c0f7997621297
6
+ metadata.gz: da7de1ce472978582caf214a2588dfe2b6248179076e221f7797a9fc218212bb4793682923ab42d3a229d5c8c9f9f1e002e0a18c823f5cd9f185923c73d33232
7
+ data.tar.gz: e191c01c8ed048d4b1812ebc78a45a0a6cab912848ea9c789a0b7a68f5481b5e51f66d4fe41c4388da590db7ccdf7a8b8d80f6947b562585efd15bbbd15a22ee
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- ruby-2.4.1
1
+ ruby-3.1.2
data/ChangeLog CHANGED
@@ -1,3 +1,23 @@
1
+ === Version 7.9 / 2022-5-25
2
+ * Enhancements (Thanks samnissen)
3
+ * Fixed yaml load issues with latest psych gem (Thanks samnissen)
4
+ * Fixed a bug with Safari browser (Thanks samnissen)
5
+ * Updated to Ruby 3.1.2 (Thanks sandeepnagra)
6
+
7
+ === Version 7.8 / 2020-7-10
8
+ * Enhancements (Thanks samnissen)
9
+ * Updated devices
10
+ * Fixed provided options and updated unit tests
11
+
12
+ === Version 7.7 / 2020-7-10
13
+ * version yanked
14
+
15
+ === Version 7.6 / 2019-2-11
16
+ * Enhancements (Thanks samnissen)
17
+ * Added support for setting browswer language
18
+ * Replaced deprecated selenium switches
19
+ * Allowed Safari browser and updated requirements to support it
20
+
1
21
  === Version 7.5 / 2017-8-22
2
22
  * Enhancements
3
23
  * Added support for modern iPhone and iPad sizes
data/README.md CHANGED
@@ -25,7 +25,7 @@ provides a UserAgent.driver method to return a new web-driver with user agent an
25
25
  * :browser
26
26
  * :firefox (default)
27
27
  * :chrome
28
- * :safari
28
+ * :safari
29
29
  * :agent
30
30
  * :iphone (default)
31
31
  * :ipad
@@ -61,6 +61,12 @@ provides a UserAgent.driver method to return a new web-driver with user agent an
61
61
  browser.goto 'tiffany.com'
62
62
  browser.url.should == 'http://m.tiffany.com/International.aspx'
63
63
 
64
+ ### A note on Safari
65
+
66
+ In our testing, it doesn't work well. Sometimes Safari Technology Preview works better, sometimes
67
+ only Safari works at all. And as of May 2021, our ability to write user agent strings
68
+ and languages for either flavor of Safari seems not to work on macOS Big Sur/Safari 14.
69
+
64
70
  ## Contributing
65
71
 
66
72
  1. Fork it
@@ -1,127 +1,174 @@
1
1
  # Desktop size sources
2
- # http://www.hobo-web.co.uk/best-screen-size/
3
- # https://en.wikipedia.org/wiki/Display_resolution#Common_display_resolutions
4
- # http://www.w3schools.com/browsers/browsers_display.asp
5
- :desktop:
6
- :user_agent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/600.8.9 (KHTML, like Gecko) Version/8.0.8 Safari/600.8.9"
7
- :portrait:
8
- :width: 768
9
- :height: 1024
10
- :landscape:
11
- :width: 1366
12
- :height: 768
13
- :iphone_default: &iphone_default
14
- :user_agent: "Mozilla/5.0 (iPhone; CPU iPhone OS 11_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/11.0 Mobile/15E148 Safari/604.1"
15
- :portrait:
16
- :width: 375
17
- :height: 635
18
- :landscape:
19
- :width: 724
20
- :height: 375
21
- :iphone: &iphone
22
- <<: *iphone_default
23
- :iphonex:
2
+ # - http://www.hobo-web.co.uk/best-screen-size/
3
+ # - https://en.wikipedia.org/wiki/Display_resolution#Common_display_resolutions
4
+ # - http://www.w3schools.com/browsers/browsers_display.asp
5
+
6
+ # iPhone and iPad data added by running Simulator on macOS and visiting
7
+ # https://whatismyviewport.com and
8
+ # https://www.whatismybrowser.com/detect/what-is-my-user-agent
9
+
10
+ # Android user agents and viewports from current android device specs.
11
+ # Tablet: Samsung Galaxy Tab S6; Phone: Google Pixel 4
12
+ # Determined without a simulator to account for software chrome,
13
+ # so these figures are necessarily larger than what will be true
14
+ # on those devices. Please feel free to submit a pull request
15
+ # with corrected and/or expanded device values.
16
+ ---
17
+ desktop:
18
+ user_agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1 Safari/605.1.15
19
+ portrait:
20
+ width: 768
21
+ height: 1024
22
+ landscape:
23
+ width: 1366
24
+ height: 768
25
+ iphone_default: &iphone_default
26
+ user_agent: Mozilla/5.0 (iPhone; CPU iPhone OS 13_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.1 Mobile/15E148 Safari/604.1
27
+ portrait:
28
+ width: 414
29
+ height: 719
30
+ landscape:
31
+ width: 808
32
+ height: 414
33
+ iphone: &iphone
24
34
  <<: *iphone_default
25
- :iphone8plus: &iphone8plus
35
+ iphone11pro:
26
36
  <<: *iphone_default
27
- :portrait:
28
- :width: 414
29
- :height: 622
30
- :landscape:
31
- :width: 736
32
- :height: 414
33
- :iphone8: &iphone8
37
+ portrait:
38
+ width: 375
39
+ height: 635
40
+ landscape:
41
+ width: 724
42
+ height: 375
43
+ iphone11promax:
34
44
  <<: *iphone_default
35
- :portrait:
36
- :width: 375
37
- :height: 553
38
- :landscape:
39
- :width: 667
40
- :height: 375
41
- :iphone7plus:
45
+ iphone11:
46
+ <<: *iphone_default
47
+ iphonese: &iphonese
48
+ <<: *iphone_default
49
+ portrait:
50
+ width: 375
51
+ height: 553
52
+ landscape:
53
+ width: 667
54
+ height: 375
55
+ iphonexr: &iphonexr
56
+ <<: *iphone_default
57
+ iphonexsmax:
58
+ <<: *iphonexr
59
+ iphonexs: &iphonexs
60
+ <<: *iphone_default
61
+ portrait:
62
+ width: 375
63
+ height: 635
64
+ landscape:
65
+ width: 724
66
+ height: 375
67
+ iphonex:
68
+ <<: *iphonexs
69
+ iphone8plus: &iphone8plus
70
+ <<: *iphone_default
71
+ portrait:
72
+ width: 414
73
+ height: 622
74
+ landscape:
75
+ width: 736
76
+ height: 414
77
+ iphone8: &iphone8
78
+ <<: *iphonese
79
+ iphone7plus:
42
80
  <<: *iphone8plus
43
- :iphone7:
81
+ iphone7:
44
82
  <<: *iphone8
45
- :portrait:
46
- :iphone6splus:
83
+ iphone6splus:
47
84
  <<: *iphone8plus
48
- :iphone6s:
85
+ iphone6s:
49
86
  <<: *iphone8
50
- :iphone6plus:
87
+ iphone6plus:
51
88
  <<: *iphone8plus
52
- :iphone6:
89
+ iphone6:
53
90
  <<: *iphone8
54
- :iphone5s: &iphone5s
91
+ iphone5s: &iphone5s
55
92
  <<: *iphone_default
56
- :portrait:
57
- :width: 320
58
- :height: 454
59
- :landscape:
60
- :width: 568
61
- :height: 320
62
- :iphonese:
93
+ portrait:
94
+ width: 320
95
+ height: 454
96
+ landscape:
97
+ width: 568
98
+ height: 320
99
+ iphonese_old:
63
100
  <<: *iphone5s
64
- :iphone5:
101
+ iphone5:
65
102
  <<: *iphone5s
66
- :iphone4s: &iphone4s
103
+ iphone4s: &iphone4s
67
104
  <<: *iphone_default
68
- :portrait:
69
- :width: 320
70
- :height: 356
71
- :landscape:
72
- :width: 480
73
- :height: 196
74
- :iphone4:
105
+ portrait:
106
+ width: 320
107
+ height: 356
108
+ landscape:
109
+ width: 480
110
+ height: 196
111
+ iphone4:
75
112
  <<: *iphone4s
76
- :ipad: &ipad
77
- :user_agent: "Mozilla/5.0 (iPad; CPU OS 11_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/11.0 Mobile/15E148 Safari/604.1"
78
- :portrait:
79
- :width: 768
80
- :height: 954
81
- :landscape:
82
- :width: 1024
83
- :height: 698
84
- :ipad_default:
113
+ ipad: &ipad
114
+ user_agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.1 Safari/605.1.15
115
+ portrait:
116
+ width: 810
117
+ height: 1010
118
+ landscape:
119
+ width: 1080
120
+ height: 740
121
+ ipad_default:
85
122
  <<: *ipad
86
- :ipad_pro: &ipad_pro
123
+ ipad_pro: &ipad_pro
87
124
  <<: *ipad
88
- :portrait:
89
- :width: 1024
90
- :height: 1296
91
- :landscape:
92
- :width: 1366
93
- :height: 954
94
- :ipad_pro_12:
125
+ portrait:
126
+ width: 1024
127
+ height: 1292
128
+ landscape:
129
+ width: 1366
130
+ height: 950
131
+ ipad_pro_12:
95
132
  <<: *ipad_pro
96
- :ipad_pro_10:
133
+ ipad_pro_11:
134
+ <<: *ipad
135
+ portrait:
136
+ width: 834
137
+ height: 1120
138
+ landscape:
139
+ width: 1194
140
+ height: 760
141
+ ipad_pro_9:
97
142
  <<: *ipad
98
- :portrait:
99
- :width: 834
100
- :height: 1042
101
- :landscape:
102
- :width: 1112
103
- :height: 764
104
- :ipad_pro_9:
143
+ portrait:
144
+ width: 768
145
+ height: 954
146
+ landscape:
147
+ width: 1024
148
+ height: 698
149
+ ipad_air: &ipad_air
105
150
  <<: *ipad
106
- :portrait:
107
- :width: 768
108
- :height: 954
109
- :landscape:
110
- :width: 1024
111
- :height: 698
112
- :android_phone:
113
- :user_agent: "Mozilla/5.0 (Linux; U; Android 4.0.1; en-us; sdk Build/ICS_MR0) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30"
114
- :portrait:
115
- :width: 320
116
- :height: 356
117
- :landscape:
118
- :width: 480
119
- :height: 196
120
- :android_tablet:
121
- :user_agent: "Mozilla/5.0 (Linux; U; Android 3.0; en-us; GT-P7100 Build/HRI83) AppleWebkit/534.13 (KHTML, like Gecko) Version/4.0 Safari/534.13"
122
- :portrait:
123
- :width: 768
124
- :height: 946
125
- :landscape:
126
- :width: 1024
127
- :height: 690
151
+ portrait:
152
+ width: 834
153
+ height: 1038
154
+ landscape:
155
+ width: 1112
156
+ height: 760
157
+ ipad_pro_10:
158
+ <<: *ipad_air
159
+ android_phone:
160
+ user_agent: Mozilla/5.0 (Linux; Android 10; Pixel) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Mobile Safari/537.36
161
+ portrait:
162
+ width: 411
163
+ height: 869
164
+ landscape:
165
+ width: 869
166
+ height: 411
167
+ android_tablet:
168
+ user_agent: Mozilla/5.0 (Linux; Android 9; SAMSUNG SM-T865) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/10.1 Chrome/71.0.3578.99 Safari/537.36
169
+ portrait:
170
+ width: 800
171
+ height: 1280
172
+ landscape:
173
+ width: 1280
174
+ height: 800
@@ -4,6 +4,9 @@ module Webdriver
4
4
  module UserAgent
5
5
 
6
6
  MINIMUM_MACOS_VERSION_NUMBER = 12
7
+ DEFAULT_BROWSER = :firefox
8
+ DEFAULT_AGENT = :iphone
9
+ DEFAULT_ORIENTATION = :portrait
7
10
 
8
11
  class BrowserOptions
9
12
 
@@ -16,7 +19,7 @@ module Webdriver
16
19
 
17
20
  options[:viewport_width], options[:viewport_height] = parse_viewport_sizes(options[:viewport_width], options[:viewport_height])
18
21
 
19
- initialize_for_browser(user_agent_string)
22
+ initialize_for_browser(user_agent_string, opts[:accept_language_string], opts[:options])
20
23
  end
21
24
 
22
25
  def method_missing(*args, &block)
@@ -27,7 +30,7 @@ module Webdriver
27
30
  end
28
31
 
29
32
  def browser_options
30
- options.except(:browser, :agent, :orientation, :user_agent_string, :viewport_width, :viewport_height)
33
+ options.except(:browser, :agent, :orientation, :user_agent_string, :accept_language_string, :viewport_width, :viewport_height, :safari_technology_preview)
31
34
  end
32
35
 
33
36
  private
@@ -41,20 +44,32 @@ module Webdriver
41
44
  @stp = false unless @stp.is_a?(TrueClass)
42
45
  end
43
46
 
44
- def initialize_for_browser(user_agent_string)
47
+ def initialize_for_browser(user_agent_string, accept_language_string, driver_options = nil)
48
+ options[:options] ||= driver_options
49
+
45
50
  case options[:browser]
46
51
  when :firefox
47
- profile ||= Selenium::WebDriver::Firefox::Profile.new
48
- profile['general.useragent.override'] = user_agent_string
49
-
50
52
  options[:options] ||= Selenium::WebDriver::Firefox::Options.new
53
+
54
+ profile ||= options[:options].profile || Selenium::WebDriver::Firefox::Profile.new
55
+ set_keys = profile.instance_variable_get(:@additional_prefs).keys
56
+
57
+ profile['general.useragent.override'] = user_agent_string if !set_keys.include?('general.useragent.override')
58
+ profile['intl.accept_languages'] = accept_language_string if accept_language_string && !set_keys.include?('intl.accept_languages')
59
+
51
60
  options[:options].profile = profile
52
61
  when :chrome
53
62
  options[:options] ||= Selenium::WebDriver::Chrome::Options.new
54
- options[:options].add_argument "--user-agent=#{user_agent_string}"
63
+
64
+ set_args = options[:options].args.map{|s| "#{s}"}.join(" ")
65
+ options[:options].add_argument "--user-agent=#{user_agent_string}" if !set_args.include?("--user-agent=")
66
+
67
+ set_prefs = options[:options].prefs.keys
68
+ options[:options].add_preference("intl.accept_languages", accept_language_string) if accept_language_string && !set_prefs.include?("intl.accept_languages")
55
69
  when :safari
70
+ options[:options] ||= Selenium::WebDriver::Safari::Options.new
56
71
  change_safari_user_agent_string(user_agent_string)
57
- options
72
+ change_safari_language(accept_language_string) if accept_language_string
58
73
  else
59
74
  raise "WebDriver UserAgent currently only supports :chrome, :firefox and :safari."
60
75
  end
@@ -67,23 +82,55 @@ module Webdriver
67
82
  end
68
83
 
69
84
  def change_safari_user_agent_string(user_agent_string)
85
+ ua = "\"\\\"#{user_agent_string}\\\"\"" # escape for shell quoting
86
+
87
+ safari_command_runner(ua, "CustomUserAgent")
88
+ end
89
+
90
+ def change_safari_language(accept_language_string)
91
+ parsed_safari_string = prepare_safari_string(accept_language_string)
92
+
93
+ safari_command_runner(parsed_safari_string, "AppleLanguages")
94
+ end
95
+
96
+ def safari_command_runner(setting, pref)
70
97
  raise "Safari requires a Mac" unless OS.mac?
71
98
 
72
- ua = "\\\"#{user_agent_string}\\\"" # escape for shell quoting
99
+ cmd = "defaults write com.apple.#{safari_version} #{pref} #{setting}"
100
+ output = `#{cmd}`
101
+
102
+ raise prepare_safari_error_message(cmd, output) unless safari_command_success?(setting, safari_version, pref, $?)
103
+ end
104
+
105
+ def safari_command_success?(setting, safari_version, pref, result)
106
+ setting_chars = "#{setting}".gsub(/\W/, '')
107
+ read_chars = `defaults read com.apple.#{safari_version} #{pref}`.gsub(/\W/, '')
108
+
109
+ setting_match = (setting_chars == read_chars)
110
+ setting_match && result.success?
111
+ end
112
+
113
+ def safari_version
73
114
  if @stp
74
115
  Selenium::WebDriver::Safari.technology_preview!
75
- cmd = "defaults write com.apple.SafariTechnologyPreview CustomUserAgent \"#{ua}\""
76
- else
77
- cmd = "defaults write com.apple.Safari CustomUserAgent \"#{ua}\""
116
+ return "SafariTechnologyPreview"
78
117
  end
79
118
 
80
- output = `#{cmd}`
119
+ "Safari"
120
+ end
81
121
 
122
+ def prepare_safari_error_message(cmd, output)
82
123
  error_message = "Unable to execute '#{cmd}'. "
83
124
  error_message += "Error message reported: '#{output}'"
84
125
  error_message += "Please execute the command manually and correct any errors."
85
126
 
86
- raise error_message unless $?.success?
127
+ error_message
128
+ end
129
+
130
+ def prepare_safari_string(accept_language_string)
131
+ ["'(", accept_language_string.split(",").map{|l|
132
+ "\"#{l.gsub(/\s+/,'')}\""
133
+ }.join(", "), ")'"].join('')
87
134
  end
88
135
 
89
136
  # Require a Mac at version 12 (Sierra) or greater
@@ -0,0 +1,32 @@
1
+ class Hash
2
+ DEEP_SYMBOLIZE_KEYS_SYMBOLS = [:deep_symbolize_keys, :deep_symbolize_keys!].freeze
3
+
4
+ def deep_copy
5
+ Marshal.load(Marshal.dump(self))
6
+ end
7
+
8
+ def method_missing(sym, *args)
9
+ super unless DEEP_SYMBOLIZE_KEYS_SYMBOLS.include?(sym)
10
+
11
+ self.send("alias_#{sym}")
12
+ end
13
+
14
+ private
15
+ def alias_deep_symbolize_keys!
16
+ alias_hash_deep_symbolize_keys!(self)
17
+ end
18
+
19
+ def alias_deep_symbolize_keys
20
+ alias_hash_deep_symbolize_keys!(self.deep_copy)
21
+ end
22
+
23
+ def alias_hash_deep_symbolize_keys!(h)
24
+ h.keys.each do |k|
25
+ ks = k.respond_to?(:to_sym) ? k.to_sym : k
26
+ h[ks] = h.delete k
27
+ alias_hash_deep_symbolize_keys! h[ks] if h[ks].kind_of? Hash
28
+ end
29
+
30
+ h
31
+ end # https://stackoverflow.com/a/8379653/1651458
32
+ end
@@ -3,20 +3,21 @@ require 'yaml'
3
3
  module Webdriver
4
4
  module UserAgent
5
5
  module Devices
6
-
6
+
7
7
  def devices
8
- YAML.load_file devices_file
8
+ string_hash = YAML.safe_load_file devices_file, aliases: true
9
+ JSON.parse(JSON[string_hash], symbolize_names: true)
9
10
  end
10
11
 
11
12
  def resolution_for(device_name, orientation, user_width, user_height)
12
13
  return [user_width.to_i, user_height.to_i] if ((user_width.to_i + user_height.to_i) > 1)
13
-
14
- device = devices[device_name.downcase][orientation.downcase]
14
+
15
+ device = devices[keyify(device_name)][keyify(orientation)]
15
16
  [device[:width],device[:height]]
16
17
  end
17
18
 
18
19
  def agent_string_for(device)
19
- device = (device ? device.downcase : :iphone)
20
+ device = (device ? keyify(device) : :iphone)
20
21
  user_agent_string = (device == :random ? random_user_agent : devices[device][:user_agent])
21
22
  raise "Unsupported user agent: '#{device}'." unless user_agent_string
22
23
  user_agent_string
@@ -24,6 +25,10 @@ module Webdriver
24
25
 
25
26
  private
26
27
 
28
+ def keyify(target)
29
+ target.downcase.to_sym
30
+ end
31
+
27
32
  def random_user_agent
28
33
  File.foreach(user_agents_file).each_with_index.reduce(nil) do |picked,pair|
29
34
  rand < 1.0/(1+pair[1]) ? pair[0] : picked
@@ -15,15 +15,6 @@ module Webdriver
15
15
  user_agent_string ||= agent_string_for opts[:agent]
16
16
  options = BrowserOptions.new(opts, user_agent_string)
17
17
  build_driver_using options
18
- ensure
19
- if safari?(opts)
20
- case
21
- when opts[:safari_technology_preview].is_a?(TrueClass)
22
- `defaults delete com.apple.SafariTechnologyPreview CustomUserAgent`
23
- else
24
- `defaults delete com.apple.Safari CustomUserAgent`
25
- end
26
- end
27
18
  end
28
19
 
29
20
  private
@@ -1,23 +1,25 @@
1
1
  require 'webdriver-user-agent/core_ext/symbol'
2
+ require 'webdriver-user-agent/core_ext/hash'
2
3
  require 'webdriver-user-agent/driver'
3
4
 
4
5
  module Webdriver
5
6
  module UserAgent
6
- def self.driver options={}
7
- Driver.instance.for options
8
- end
7
+ class << self
8
+ def driver(options = {})
9
+ Driver.instance.for options
10
+ end
9
11
 
10
- def self.devices
11
- Driver.instance.devices
12
- end
12
+ def devices
13
+ Driver.instance.devices
14
+ end
13
15
 
14
- def self.resolution_for device_name, orientation
15
- Driver.instance.resolution_for device_name, orientation
16
- end
17
-
18
- def self.agent_string_for device
19
- Driver.instance.agent_string_for device
20
- end
16
+ def resolution_for(device_name, orientation)
17
+ Driver.instance.resolution_for device_name, orientation
18
+ end
21
19
 
20
+ def agent_string_for(device)
21
+ Driver.instance.agent_string_for device
22
+ end
23
+ end
22
24
  end
23
25
  end
@@ -5,17 +5,93 @@ $LOAD_PATH.unshift(File.dirname(__FILE__))
5
5
  require 'webdriver-user-agent'
6
6
  require 'selenium-webdriver'
7
7
  require 'watir'
8
+ require 'webdrivers'
8
9
 
9
- CHROMEBROWSER_UICHROME_HEIGHT = 114
10
- CHROMEBROWSER_UICHROME_HEIGHT_TALL = 41
11
- CHROMEBROWSER_UI_MINIMUM_HEIGHT = 158
12
- FIREFOXBROWSER_UICHROME_HEIGHT = 74
10
+ CHROMEBROWSER_UICHROME_HEIGHT = 124
11
+ CHROMEBROWSER_UICHROME_HEIGHT_TALL = 50
12
+ CHROMEBROWSER_UI_MINIMUM_HEIGHT = 289
13
+ FIREFOXBROWSER_UICHROME_HEIGHT = 85
14
+ FIREFOXBROWSER_MINIMUM_WIDTH = 450
13
15
  SAFARIBROWSER_UICHROME_HEIGHT = 38
16
+ SIZE_FUDGE_FACTOR = 0.05
17
+
18
+ RSpec.shared_examples "browser driver" do
19
+ it "creates the browser driver" do
20
+ expect("#{driver.browser}").to match(/#{Regexp.quote(browser.to_s)}/i)
21
+ end
22
+
23
+ it "matches the agent partial" do
24
+ expect(driver.execute_script(agent_script)).to include agent_match
25
+ end
26
+ end
27
+
28
+ RSpec.shared_examples "random browser driver" do
29
+ it "creates the browser driver" do
30
+ expect("#{driver.browser}").to match(/#{Regexp.quote(browser.to_s)}/i)
31
+ end
32
+
33
+ it "matches the agent partial" do
34
+ expect(driver.execute_script(agent_script)).not_to be_nil
35
+ end
36
+ end
37
+
38
+ RSpec.shared_examples "firefox size" do
39
+ it "matches the expected width" do
40
+ width_expectation = device.dig(orientation.downcase.to_sym, :width)
41
+ width_expectation = FIREFOXBROWSER_MINIMUM_WIDTH if width_expectation < FIREFOXBROWSER_MINIMUM_WIDTH
42
+ width_expectation_fudge = width_expectation.to_f * SIZE_FUDGE_FACTOR
43
+ expect(driver.execute_script(width_script)).to be_within(width_expectation_fudge).of(width_expectation)
44
+ end
45
+
46
+ it "matches the expected height" do
47
+ height_expectation = device.dig(orientation.downcase.to_sym, :height) - FIREFOXBROWSER_UICHROME_HEIGHT
48
+ height_expectation_fudge = height_expectation.to_f * SIZE_FUDGE_FACTOR
49
+ expect(driver.execute_script(height_script)).to be_within(height_expectation_fudge).of(height_expectation)
50
+ end
51
+ end
52
+
53
+ RSpec.shared_examples "safari size" do
54
+ it "matches the expected width" do
55
+ width_expectation = device.dig(orientation.downcase.to_sym, :width)
56
+ width_expectation_fudge = width_expectation.to_f * SIZE_FUDGE_FACTOR
57
+ expect(driver.execute_script(width_script)).to be_within(width_expectation_fudge).of(width_expectation)
58
+ end
59
+
60
+ it "matches the expected height" do
61
+ height_expectation = device.dig(orientation.downcase.to_sym, :height) - SAFARIBROWSER_UICHROME_HEIGHT
62
+ height_expectation_fudge = height_expectation.to_f * SIZE_FUDGE_FACTOR
63
+ expect(driver.execute_script(height_script)).to be_within(height_expectation_fudge).of(height_expectation)
64
+ end
65
+ end
66
+
67
+ RSpec.shared_examples "chrome size" do
68
+ it "matches the expected width" do
69
+ width_expectation = device.dig(orientation.downcase.to_sym, :width)
70
+ width_expectation_fudge = width_expectation.to_f * SIZE_FUDGE_FACTOR
71
+ expect(driver.execute_script(width_script)).to be_within(width_expectation_fudge).of(width_expectation)
72
+ end
73
+
74
+ it "matches the expected height" do
75
+ height_expectation = device.dig(orientation.downcase.to_sym, :height) - CHROMEBROWSER_UICHROME_HEIGHT
76
+ height_expectation_fudge = height_expectation.to_f * SIZE_FUDGE_FACTOR
77
+ expect(driver.execute_script(height_script)).to be_within(height_expectation_fudge).of(height_expectation)
78
+ end
79
+ end
14
80
 
15
81
  describe "webdriver user agent" do
82
+ let(:devices) { Webdriver::UserAgent.devices }
83
+ let(:agent_script) { 'return navigator.userAgent' }
84
+ let(:width_script) { 'return Math.max(document.documentElement.clientWidth, window.innerWidth || 0)' }
85
+ let(:height_script) { 'return Math.max(document.documentElement.clientHeight, window.innerHeight || 0)' }
86
+
16
87
  after :each do
17
- @browser.close if @browser rescue nil
18
- @driver.quit if @driver rescue nil
88
+ driver.quit if defined?(driver) rescue Selenium::WebDriver::Error::SessionNotCreatedError
89
+ browser.close if defined?(browser) && browser&.is_a?(Watir::Browser)
90
+ `defaults delete com.apple.SafariTechnologyPreview CustomUserAgent >/dev/null 2>/dev/null`
91
+ `defaults delete com.apple.SafariTechnologyPreview AppleLanguages >/dev/null 2>/dev/null`
92
+ `defaults delete com.apple.Safari CustomUserAgent >/dev/null 2>/dev/null`
93
+ `defaults delete com.apple.Safari AppleLanguages >/dev/null 2>/dev/null`
94
+ sleep(0.5) # Safari needs time to shutdown
19
95
  end
20
96
 
21
97
  # window.innerWidth and window.innerHeight
@@ -23,37 +99,129 @@ describe "webdriver user agent" do
23
99
  # browser widths and heights
24
100
  # http://stackoverflow.com/a/8876069/1651458
25
101
 
26
- it "can create a new webdriver driver using firefox and iphone (portrait) by default" do
27
- @driver = Webdriver::UserAgent.driver
28
- expect(@driver.browser).to eq(:firefox)
29
- expect(@driver.execute_script('return navigator.userAgent')).to include 'iPhone'
30
- expect(@driver.execute_script('return Math.max(document.documentElement.clientWidth, window.innerWidth || 0)')).to eq(375)
31
- expect(@driver.execute_script('return Math.max(document.documentElement.clientHeight, window.innerHeight || 0)')).to eq(635 - FIREFOXBROWSER_UICHROME_HEIGHT)
102
+ context "standard browser, agent or orientation set" do
103
+ let(:device) { devices[:iphone] }
104
+ let(:driver) { Webdriver::UserAgent.driver }
105
+ let(:browser) { "firefox" }
106
+ let(:orientation) { :portrait }
107
+ let(:agent_match) { 'iPhone' }
108
+
109
+ it_behaves_like "browser driver"
110
+ it_behaves_like "firefox size"
111
+ end
112
+
113
+ context "device, browser, orientation, agent are all symbols" do
114
+ let(:device) { devices[:iphone] }
115
+ let(:device_key) { :iphone }
116
+ let(:browser) { :firefox }
117
+ let(:orientation) { :landscape }
118
+ let(:driver) { Webdriver::UserAgent.driver(
119
+ browser: browser,
120
+ agent: device_key,
121
+ orientation: orientation) }
122
+ let(:agent_match) { 'iPhone' }
123
+
124
+ it_behaves_like "browser driver"
125
+ it_behaves_like "firefox size"
32
126
  end
127
+
128
+ context "browser is a symbol; device, orientation, agent are all strings" do
129
+ let(:device) { devices[:iphone] }
130
+ let(:device_key) { "iPhone" }
131
+ let(:browser) { :firefox }
132
+ let(:orientation) { "Portrait" }
133
+ let(:driver) { Webdriver::UserAgent.driver(
134
+ browser: browser,
135
+ agent: device_key,
136
+ orientation: orientation) }
137
+ let(:agent_match) { 'iPhone' }
138
+
139
+ it_behaves_like "browser driver"
140
+ it_behaves_like "firefox size"
141
+ end
142
+
143
+ context "Safari browser, iPhone 11 Pro Max agent, landscape orientation" do
144
+ let(:device) { devices[:iphone11promax] }
145
+ let(:orientation) { :landscape }
146
+ let(:driver) do
147
+ # --- On Safari ---
148
+ # Safari is a mess. We do our best to test it, but
149
+ # it is too unreliable. The gem will still try to provide
150
+ # these features for the time being.
151
+ # If you are a subject matter expert, please
152
+ # get in touch. - Sam
33
153
 
34
- it "can create a new webdriver driver using safari and iphone 6 plus, and landscape" do
35
- @driver = Webdriver::UserAgent.driver(:browser => :safari, :agent => :iphone6plus, :orientation => :landscape)
36
- expect(@driver.browser).to eq(:safari)
154
+ Webdriver::UserAgent.driver(
155
+ browser: :safari,
156
+ agent: :iphone11promax,
157
+ orientation: orientation
158
+ )
159
+ end
160
+ let(:browser) { "safari" }
161
+ let(:orientation) { :landscape }
162
+ let(:agent_match) { 'iPhone' }
37
163
 
38
- expect(@driver.execute_script('return navigator.userAgent')).to include 'iPhone'
39
- expect(@driver.execute_script('return Math.max(document.documentElement.clientWidth, window.innerWidth || 0)')).to eq(736)
40
- expect(@driver.execute_script('return Math.max(document.documentElement.clientHeight, window.innerHeight || 0)')).to eq(414 - SAFARIBROWSER_UICHROME_HEIGHT)
164
+ # pending("a stable, documented way to programmatically change Safari details") { it_behaves_like "browser driver" }
165
+ # But there doesn't seem to be any way for RSpec to handle the above?
166
+ # `it_behaves_like` isn't available inside `pending`, but `pending` isn't available at
167
+ # the `context` level.
168
+ it_behaves_like "safari size"
41
169
  end
42
170
 
43
- it "can create a new webdriver driver using chrome and iphone 6 plus (landscape)" do
44
- @driver = Webdriver::UserAgent.driver(:browser => :chrome, :agent => :iphone6plus, :orientation => :landscape)
45
- expect(@driver.browser).to eq(:chrome)
46
- expect(@driver.execute_script('return navigator.userAgent')).to include 'iPhone'
47
- expect(@driver.execute_script('return Math.max(document.documentElement.clientWidth, window.innerWidth || 0)')).to eq(736)
48
- expect(@driver.execute_script('return Math.max(document.documentElement.clientHeight, window.innerHeight || 0)')).to eq(414 - CHROMEBROWSER_UICHROME_HEIGHT)
171
+ context "Safari browser, iPhone 6 Plus agent, landscape orientation" do
172
+ let(:device) { devices[:iphone6plus] }
173
+ let(:orientation) { :landscape }
174
+ let(:driver) do
175
+ Webdriver::UserAgent.driver(
176
+ browser: :safari,
177
+ agent: :iphone6plus,
178
+ orientation: orientation
179
+ )
180
+ end
181
+ let(:browser) { "safari" }
182
+ let(:agent_match) { 'iPhone' }
183
+
184
+ # pending("a stable, documented way to programmatically change Safari details") { it_behaves_like "browser driver" }
185
+ # But there doesn't seem to be any way for RSpec to handle the above?
186
+ # `it_behaves_like` isn't available inside `pending`, but `pending` isn't available at
187
+ # the `context` level.
188
+ it_behaves_like "safari size"
49
189
  end
50
190
 
51
- it "can create a new webdriver driver using chrome and iPad (landscape)" do
52
- @driver = Webdriver::UserAgent.driver(:browser => :chrome, :agent => :ipad, :orientation => :landscape)
53
- expect(@driver.browser).to eq(:chrome)
54
- expect(@driver.execute_script('return navigator.userAgent')).to include 'iPad'
55
- expect(@driver.execute_script('return Math.max(document.documentElement.clientWidth, window.innerWidth || 0)')).to eq(1024)
56
- expect(@driver.execute_script('return Math.max(document.documentElement.clientHeight, window.innerHeight || 0)')).to eq(698 - CHROMEBROWSER_UICHROME_HEIGHT)
191
+ context "Chrome browser, iPhone XS agent, landscape orientation" do
192
+ let(:device_key) { :iphonexs }
193
+ let(:device) { devices[device_key] }
194
+ let(:orientation) { :landscape }
195
+ let(:driver) do
196
+ Webdriver::UserAgent.driver(
197
+ browser: :chrome,
198
+ agent: device_key,
199
+ orientation: orientation
200
+ )
201
+ end
202
+ let(:browser) { "chrome" }
203
+ let(:agent_match) { 'iPhone' }
204
+
205
+ it_behaves_like "browser driver"
206
+ it_behaves_like "chrome size"
207
+ end
208
+
209
+ context "Chrome browser, iPhone XS agent, landscape orientation" do
210
+ let(:device_key) { :iphone6 }
211
+ let(:device) { devices[device_key] }
212
+ let(:orientation) { :landscape }
213
+ let(:driver) do
214
+ Webdriver::UserAgent.driver(
215
+ browser: :chrome,
216
+ agent: device_key,
217
+ orientation: orientation
218
+ )
219
+ end
220
+ let(:browser) { "chrome" }
221
+ let(:agent_match) { 'Mac OS' }
222
+
223
+ it_behaves_like "browser driver"
224
+ it_behaves_like "chrome size"
57
225
  end
58
226
 
59
227
  it "can create a new webdriver driver using chrome and iPad Pro (portrait)" do
@@ -72,100 +240,196 @@ describe "webdriver user agent" do
72
240
 
73
241
  @driver = Webdriver::UserAgent.driver(:browser => :chrome, :agent => :ipad_pro, :orientation => :portrait)
74
242
  expect(@driver.browser).to eq(:chrome)
75
- expect(@driver.execute_script('return navigator.userAgent')).to include 'iPad'
243
+ expect(@driver.execute_script('return navigator.userAgent')).to include 'Mac OS'
76
244
  expect(@driver.execute_script('return Math.max(document.documentElement.clientWidth, window.innerWidth || 0)')).to eq(1024)
77
245
 
78
246
  # See above
79
247
  if @you_have_a_tall_monitor
80
- expect(@driver.execute_script('return Math.max(document.documentElement.clientHeight, window.innerHeight || 0)')).to eq(1302 - CHROMEBROWSER_UICHROME_HEIGHT)
81
- end
248
+ expect(@driver.execute_script('return Math.max(document.documentElement.clientHeight, window.innerHeight || 0)')).to eq(1302 - CHROMEBROWSER_UICHROME_HEIGHT)
249
+ end
82
250
  end
83
251
 
84
- it "can create a new webdriver driver using firefox and android phone (landscape)" do
85
- @driver = Webdriver::UserAgent.driver(:browser => :chrome, :agent => :android_phone, :orientation => :landscape)
86
- expect(@driver.browser).to eq(:chrome)
87
- expect(@driver.execute_script('return navigator.userAgent')).to include 'Android'
88
- expect(@driver.execute_script('return Math.max(document.documentElement.clientWidth, window.innerWidth || 0)')).to eq(480)
89
-
90
- # Chrome is apparently setting some kind of minimum height
91
- # As seen on Chrome v42 on OS X Yosimite
92
- expect(@driver.execute_script('return Math.max(document.documentElement.clientHeight, window.innerHeight || 0)')).to eq(CHROMEBROWSER_UI_MINIMUM_HEIGHT)
252
+ context "Chrome browser, Android tablet agent, landscape orientation" do
253
+ let(:device_key) { :android_phone }
254
+ let(:device) { devices[device_key] }
255
+ let(:orientation) { :landscape }
256
+ let(:driver) do
257
+ Webdriver::UserAgent.driver(
258
+ browser: :chrome,
259
+ agent: device_key,
260
+ orientation: orientation
261
+ )
262
+ end
263
+ let(:browser) { "chrome" }
264
+ let(:agent_match) { 'Android' }
93
265
 
266
+ it_behaves_like "browser driver"
267
+ it_behaves_like "chrome size"
94
268
  end
95
269
 
96
- it "can create a new webdriver driver using chrome and android tablet (portrait)" do
97
- @driver = Webdriver::UserAgent.driver(:browser => :chrome, :agent => :android_tablet, :orientation => :portrait)
98
- expect(@driver.browser).to eq(:chrome)
99
- expect(@driver.execute_script('return navigator.userAgent')).to include 'Android'
100
- expect(@driver.execute_script('return Math.max(document.documentElement.clientWidth, window.innerWidth || 0)')).to eq(768)
101
- expect(@driver.execute_script('return Math.max(document.documentElement.clientHeight, window.innerHeight || 0)')).to eq(873 - CHROMEBROWSER_UICHROME_HEIGHT_TALL)
270
+ context "Firefox browser, desktop agent, landscape orientation" do
271
+ let(:device_key) { :desktop }
272
+ let(:device) { devices[device_key] }
273
+ let(:orientation) { :landscape }
274
+ let(:driver) do
275
+ Webdriver::UserAgent.driver(
276
+ browser: :firefox,
277
+ agent: device_key,
278
+ orientation: orientation
279
+ )
280
+ end
281
+ let(:browser) { "firefox" }
282
+ let(:agent_match) { 'Mac OS' }
283
+
284
+ it_behaves_like "browser driver"
285
+ it_behaves_like "firefox size"
102
286
  end
103
287
 
104
- it "can create a new webdriver driver using firefox and desktop (landscape)" do
105
- @driver = Webdriver::UserAgent.driver(:browser => :firefox, :agent => :desktop, :orientation => :landscape)
106
- expect(@driver.browser).to eq(:firefox)
107
- expect(@driver.execute_script('return navigator.userAgent')).to include 'Mac OS X'
108
- expect(@driver.execute_script('return Math.max(document.documentElement.clientWidth, window.innerWidth || 0)')).to eq(1366)
109
- expect(@driver.execute_script('return Math.max(document.documentElement.clientHeight, window.innerHeight || 0)')).to eq(768 - FIREFOXBROWSER_UICHROME_HEIGHT)
288
+ context "random agent" do
289
+ context "no specified browser" do
290
+ let(:device_key) { :random }
291
+ let(:driver) { Webdriver::UserAgent.driver(agent: device_key) }
292
+ let(:browser) { :firefox }
293
+
294
+ it_behaves_like "random browser driver"
295
+ end
296
+
297
+ context "chrome browser" do
298
+ let(:device_key) { :random }
299
+ let(:browser) { :chrome }
300
+ let(:driver) do
301
+ Webdriver::UserAgent.driver(browser: browser, agent: device_key)
302
+ end
303
+
304
+ it_behaves_like "random browser driver"
305
+ end
110
306
  end
111
307
 
112
- it "can create a new webdriver driver using firefox and random user agent" do
113
- @driver = Webdriver::UserAgent.driver(:agent => :random)
114
- expect(@driver.browser).to eq(:firefox)
115
- expect(@driver.execute_script('return navigator.userAgent')).not_to be_nil
116
- expect(@driver.execute_script('return Math.max(document.documentElement.clientWidth, window.innerWidth || 0)')).not_to eq(320)
117
- expect(@driver.execute_script('return Math.max(document.documentElement.clientHeight, window.innerHeight || 0)')).not_to eq(356 - FIREFOXBROWSER_UICHROME_HEIGHT)
308
+ context "existing firefox profile" do
309
+ let(:device) { devices[:iphone] }
310
+ let(:profile) do
311
+ profile = Selenium::WebDriver::Firefox::Profile.new
312
+ profile["intl.accept_languages"] = "es-MX"
313
+ profile
314
+ end
315
+ let(:options) { Selenium::WebDriver::Firefox::Options.new(profile: profile) }
316
+ let(:browser) { :firefox }
317
+ let(:agent_match) { 'iPhone' }
318
+ let(:orientation) { :portrait }
319
+ let(:driver) { Webdriver::UserAgent.driver(browser: browser, options: options) }
320
+
321
+ it_behaves_like "browser driver"
322
+ it_behaves_like "firefox size"
323
+
324
+ it "absorbs the options' profile" do
325
+ expect(driver.execute_script("return (navigator.language || navigator.userLanguage)")).to include("es-MX")
326
+ end
118
327
  end
119
328
 
120
- it "can create a new webdriver driver using chrome and random user agent" do
121
- @driver = Webdriver::UserAgent.driver(:browser => :chrome, :agent => :random)
122
- expect(@driver.browser).to eq(:chrome)
123
- expect(@driver.execute_script('return navigator.userAgent')).not_to be_nil
124
- expect(@driver.execute_script('return Math.max(document.documentElement.clientWidth, window.innerWidth || 0)')).not_to eq(320)
125
- expect(@driver.execute_script('return Math.max(document.documentElement.clientHeight, window.innerHeight || 0)')).not_to eq(356 - CHROMEBROWSER_UICHROME_HEIGHT)
329
+ context "user-provided user agent string for firefox" do
330
+ let(:browser) { :firefox }
331
+ let(:user_agent) { "Mozilla/4.0 (compatible; MSIE 5.5b1; Mac_PowerPC)" }
332
+ let(:driver) { Webdriver::UserAgent.driver(user_agent_string: user_agent) }
333
+
334
+ it "can create a new webdriver driver" do
335
+ expect("#{driver.browser}").to match(/#{Regexp.quote(browser.to_s)}/i)
336
+
337
+ expect(driver.execute_script("return navigator.userAgent")).to include("Mac_PowerPC")
338
+ end
126
339
  end
127
340
 
128
- it "can create a new webdriver driver using an existing firefox profile" do
129
- profile = Selenium::WebDriver::Firefox::Profile.new
130
- profile['browser.startup.homepage'] = "data:text/html,<title>hello</title>"
131
- options = Selenium::WebDriver::Firefox::Options.new
132
- options.profile = profile
133
- @driver = Webdriver::UserAgent.driver(:browser => :firefox, options: options)
341
+ context "user-provided accept language string for firefox" do
342
+ let(:browser) { :firefox }
343
+ let(:language) { "es-ES, es-MX;q=0.9, es;q=0.5, *;0.4" }
344
+ let(:driver) { Webdriver::UserAgent.driver(accept_language_string: language) }
134
345
 
135
- expect(@driver.browser).to eq(:firefox)
136
- expect(@driver.execute_script('return navigator.userAgent')).to include 'iPhone'
137
- expect(@driver.execute_script('return Math.max(document.documentElement.clientWidth, window.innerWidth || 0)')).to eq(375)
138
- expect(@driver.execute_script('return Math.max(document.documentElement.clientHeight, window.innerHeight || 0)')).to eq(635 - FIREFOXBROWSER_UICHROME_HEIGHT)
346
+ it "can create a new webdriver driver" do
347
+ expect("#{driver.browser}").to match(/#{Regexp.quote(browser.to_s)}/i)
348
+
349
+ expect(driver.execute_script("return (navigator.language || navigator.userLanguage)")).to include("es-ES")
350
+ end
139
351
  end
140
352
 
141
- it "can create a new webdriver driver using firefox and user-specified user agent" do
142
- @driver = Webdriver::UserAgent.driver(:user_agent_string => "Mozilla/4.0 (compatible; MSIE 5.5b1; Mac_PowerPC)")
143
- expect(@driver.browser).to eq(:firefox)
144
- expect(@driver.execute_script('return navigator.userAgent')).to include 'Mac_PowerPC'
353
+ context "user-provided accept language string for safari" do
354
+ let(:browser) { :safari }
355
+ let(:language) { "es-ES, es-MX;q=0.9, es;q=0.5, *;0.4" }
356
+ let(:driver) {
357
+ Webdriver::UserAgent.driver(
358
+ browser: browser,
359
+ accept_language_string: language
360
+ )
361
+ }
145
362
 
146
- @browser = Watir::Browser.new @driver
147
- end
363
+ it "can create a new webdriver driver" do
364
+ expect("#{driver.browser}").to match(/#{Regexp.quote(browser.to_s)}/i)
365
+ end
366
+
367
+ pending("a stable, documented way to programmatically change Safari details") do
368
+ expect(driver.execute_script("return (navigator.language || navigator.userLanguage)")).to include("es-es")
369
+ end
370
+ end
148
371
 
149
- it "can create a new webdriver driver using firefox and user-specified viewport sizes (string or int)" do
150
- width = 800
151
- height = 600
372
+ context "user-provided viewport size and agent for firefox" do
373
+ let(:browser) { :firefox }
374
+ let(:device_key) { :iphone11 }
375
+ let(:device) { devices[device_key] }
376
+ let(:width) { 800 }
377
+ let(:height) { 600 }
378
+ let(:agent_match) { 'iPhone' }
379
+ let(:orientation) { :portrait }
380
+ let(:driver) {
381
+ Webdriver::UserAgent.driver(
382
+ viewport_width: "#{width}",
383
+ viewport_height: height,
384
+ agent: device_key
385
+ )
386
+ }
152
387
 
153
- @driver = Webdriver::UserAgent.driver(:viewport_width => "#{width}", :viewport_height => height, :agent => :iphone6)
154
- expect(@driver.execute_script('return Math.max(document.documentElement.clientWidth, window.innerWidth || 0)')).to eq(800)
155
- expect(@driver.execute_script('return Math.max(document.documentElement.clientHeight, window.innerHeight || 0)')).to eq(600 - FIREFOXBROWSER_UICHROME_HEIGHT)
156
- end
388
+ it_behaves_like "browser driver"
389
+ it "uses user-provided dimensions" do
390
+ expect(driver.execute_script(width_script)).to eq(width)
391
+ expect(driver.execute_script(height_script)).to eq(height - FIREFOXBROWSER_UICHROME_HEIGHT)
392
+ end
393
+ end
157
394
 
158
- it "can create a new webdriver driver, handling for nonsense height and widths" do
159
- @driver = Webdriver::UserAgent.driver(:viewport_width => "abc", :agent => :iphone8)
160
- expect(@driver.execute_script('return Math.max(document.documentElement.clientWidth, window.innerWidth || 0)')).to eq(375)
161
- expect(@driver.execute_script('return Math.max(document.documentElement.clientHeight, window.innerHeight || 0)')).to eq(553 - FIREFOXBROWSER_UICHROME_HEIGHT)
162
- end
395
+ context "user-provided nonsense viewport size for firefox" do
396
+ let(:browser) { :firefox }
397
+ let(:device_key) { :iphone8 }
398
+ let(:device) { devices[device_key] }
399
+ let(:width) { "xyz" }
400
+ let(:agent_match) { 'iPhone' }
401
+ let(:orientation) { :portrait }
402
+ let(:driver) {
403
+ Webdriver::UserAgent.driver(
404
+ viewport_width: "#{width}",
405
+ agent: device_key
406
+ )
407
+ }
163
408
 
164
- it "can allow using selenium driver for watir browser" do
165
- @driver = Webdriver::UserAgent.driver(:browser => :firefox, :agent => :iphone, :orientation => :portrait)
166
- @browser = Watir::Browser.new @driver
167
- expect(@browser).to be_a(Watir::Browser)
168
- expect(@browser.url).to be_a(String)
409
+ it_behaves_like "browser driver"
410
+ it_behaves_like "firefox size"
169
411
  end
170
412
 
413
+ context "portrait firefox iphone" do
414
+ let(:browser) { :firefox }
415
+ let(:device_key) { :iphone }
416
+ let(:device) { devices[device_key] }
417
+ let(:width) { "xyz" }
418
+ let(:agent_match) { 'iPhone' }
419
+ let(:orientation) { :portrait }
420
+ let(:driver) {
421
+ Webdriver::UserAgent.driver(
422
+ agent: device_key,
423
+ browser: browser,
424
+ orientation: orientation
425
+ )
426
+ }
427
+
428
+ it "can create a browser using the driver" do
429
+ browser = Watir::Browser.new(driver)
430
+
431
+ expect(browser).to be_a(Watir::Browser)
432
+ expect(browser.url).to be_a(String)
433
+ end
434
+ end
171
435
  end
@@ -12,7 +12,7 @@ Gem::Specification.new do |gem|
12
12
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
13
13
  gem.name = "webdriver-user-agent"
14
14
  gem.require_paths = ["lib"]
15
- gem.version = "7.5"
15
+ gem.version = "7.9"
16
16
  gem.requirements << 'chromedriver, v2.20'
17
17
  # chromedriver v2.19 causes
18
18
  # Selenium::WebDriver::Error::NoSuchDriverError: no such session errors
@@ -23,4 +23,5 @@ Gem::Specification.new do |gem|
23
23
  gem.add_dependency 'psych'
24
24
  gem.add_development_dependency 'rspec'
25
25
  gem.add_development_dependency 'watir'
26
+ gem.add_development_dependency 'webdrivers'
26
27
  end
metadata CHANGED
@@ -1,17 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: webdriver-user-agent
3
3
  version: !ruby/object:Gem::Version
4
- version: '7.5'
4
+ version: '7.9'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alister Scott
8
8
  - Jeff Morgan
9
9
  - Sandeep Singh
10
10
  - Sam Nissen
11
- autorequire:
11
+ autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2018-08-21 00:00:00.000000000 Z
14
+ date: 2022-05-25 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: selenium-webdriver
@@ -111,6 +111,20 @@ dependencies:
111
111
  - - ">="
112
112
  - !ruby/object:Gem::Version
113
113
  version: '0'
114
+ - !ruby/object:Gem::Dependency
115
+ name: webdrivers
116
+ requirement: !ruby/object:Gem::Requirement
117
+ requirements:
118
+ - - ">="
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
121
+ type: :development
122
+ prerelease: false
123
+ version_requirements: !ruby/object:Gem::Requirement
124
+ requirements:
125
+ - - ">="
126
+ - !ruby/object:Gem::Version
127
+ version: '0'
114
128
  description: A helper gem to emulate populate device user agents and resolutions when
115
129
  using webdriver
116
130
  email:
@@ -136,6 +150,7 @@ files:
136
150
  - lib/device-info/user_agents.txt
137
151
  - lib/webdriver-user-agent.rb
138
152
  - lib/webdriver-user-agent/browser_options.rb
153
+ - lib/webdriver-user-agent/core_ext/hash.rb
139
154
  - lib/webdriver-user-agent/core_ext/symbol.rb
140
155
  - lib/webdriver-user-agent/devices.rb
141
156
  - lib/webdriver-user-agent/driver.rb
@@ -144,7 +159,7 @@ files:
144
159
  homepage: https://github.com/alisterscott/webdriver-user-agent
145
160
  licenses: []
146
161
  metadata: {}
147
- post_install_message:
162
+ post_install_message:
148
163
  rdoc_options: []
149
164
  require_paths:
150
165
  - lib
@@ -160,9 +175,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
160
175
  version: '0'
161
176
  requirements:
162
177
  - chromedriver, v2.20
163
- rubyforge_project:
164
- rubygems_version: 2.7.7
165
- signing_key:
178
+ rubygems_version: 3.3.7
179
+ signing_key:
166
180
  specification_version: 4
167
181
  summary: A helper gem to emulate populate device user agents and resolutions when
168
182
  using webdriver