webdriver-user-agent 7.5 → 7.9

Sign up to get free protection for your applications and to get access to all the features.
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