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 +4 -4
- data/.ruby-version +1 -1
- data/ChangeLog +20 -0
- data/README.md +7 -1
- data/lib/device-info/devices.yaml +154 -107
- data/lib/webdriver-user-agent/browser_options.rb +61 -14
- data/lib/webdriver-user-agent/core_ext/hash.rb +32 -0
- data/lib/webdriver-user-agent/devices.rb +10 -5
- data/lib/webdriver-user-agent/driver.rb +0 -9
- data/lib/webdriver-user-agent.rb +15 -13
- data/spec/webdriver-user-agent_spec.rb +363 -99
- data/webdriver-user-agent.gemspec +2 -1
- metadata +21 -7
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c8f285c93bdc6daea5d101e3a61b973a82c9e25152ec14fbd90223ea382cd4ab
|
|
4
|
+
data.tar.gz: ff356f5cf939d1ea35ec8197ec9ccbc455c203458729da220016f7d861961b20
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: da7de1ce472978582caf214a2588dfe2b6248179076e221f7797a9fc218212bb4793682923ab42d3a229d5c8c9f9f1e002e0a18c823f5cd9f185923c73d33232
|
|
7
|
+
data.tar.gz: e191c01c8ed048d4b1812ebc78a45a0a6cab912848ea9c789a0b7a68f5481b5e51f66d4fe41c4388da590db7ccdf7a8b8d80f6947b562585efd15bbbd15a22ee
|
data/.ruby-version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
ruby-
|
|
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
|
-
|
|
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
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
:
|
|
22
|
-
|
|
23
|
-
:
|
|
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
|
-
:
|
|
35
|
+
iphone11pro:
|
|
26
36
|
<<: *iphone_default
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
:
|
|
37
|
+
portrait:
|
|
38
|
+
width: 375
|
|
39
|
+
height: 635
|
|
40
|
+
landscape:
|
|
41
|
+
width: 724
|
|
42
|
+
height: 375
|
|
43
|
+
iphone11promax:
|
|
34
44
|
<<: *iphone_default
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
:
|
|
41
|
-
:
|
|
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
|
-
|
|
81
|
+
iphone7:
|
|
44
82
|
<<: *iphone8
|
|
45
|
-
|
|
46
|
-
:iphone6splus:
|
|
83
|
+
iphone6splus:
|
|
47
84
|
<<: *iphone8plus
|
|
48
|
-
|
|
85
|
+
iphone6s:
|
|
49
86
|
<<: *iphone8
|
|
50
|
-
|
|
87
|
+
iphone6plus:
|
|
51
88
|
<<: *iphone8plus
|
|
52
|
-
|
|
89
|
+
iphone6:
|
|
53
90
|
<<: *iphone8
|
|
54
|
-
|
|
91
|
+
iphone5s: &iphone5s
|
|
55
92
|
<<: *iphone_default
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
:
|
|
93
|
+
portrait:
|
|
94
|
+
width: 320
|
|
95
|
+
height: 454
|
|
96
|
+
landscape:
|
|
97
|
+
width: 568
|
|
98
|
+
height: 320
|
|
99
|
+
iphonese_old:
|
|
63
100
|
<<: *iphone5s
|
|
64
|
-
|
|
101
|
+
iphone5:
|
|
65
102
|
<<: *iphone5s
|
|
66
|
-
|
|
103
|
+
iphone4s: &iphone4s
|
|
67
104
|
<<: *iphone_default
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
105
|
+
portrait:
|
|
106
|
+
width: 320
|
|
107
|
+
height: 356
|
|
108
|
+
landscape:
|
|
109
|
+
width: 480
|
|
110
|
+
height: 196
|
|
111
|
+
iphone4:
|
|
75
112
|
<<: *iphone4s
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
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
|
-
|
|
123
|
+
ipad_pro: &ipad_pro
|
|
87
124
|
<<: *ipad
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
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
|
-
:
|
|
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
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
:
|
|
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
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
:
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
:
|
|
119
|
-
|
|
120
|
-
:
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
:
|
|
127
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
76
|
-
else
|
|
77
|
-
cmd = "defaults write com.apple.Safari CustomUserAgent \"#{ua}\""
|
|
116
|
+
return "SafariTechnologyPreview"
|
|
78
117
|
end
|
|
79
118
|
|
|
80
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
|
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
|
|
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
|
data/lib/webdriver-user-agent.rb
CHANGED
|
@@ -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
|
-
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
class << self
|
|
8
|
+
def driver(options = {})
|
|
9
|
+
Driver.instance.for options
|
|
10
|
+
end
|
|
9
11
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
def devices
|
|
13
|
+
Driver.instance.devices
|
|
14
|
+
end
|
|
13
15
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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 =
|
|
10
|
-
CHROMEBROWSER_UICHROME_HEIGHT_TALL =
|
|
11
|
-
CHROMEBROWSER_UI_MINIMUM_HEIGHT =
|
|
12
|
-
FIREFOXBROWSER_UICHROME_HEIGHT =
|
|
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
|
-
|
|
18
|
-
|
|
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
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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
|
-
|
|
35
|
-
|
|
36
|
-
|
|
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
|
-
|
|
39
|
-
|
|
40
|
-
|
|
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
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
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
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
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 '
|
|
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
|
-
|
|
81
|
-
|
|
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
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
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
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
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
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
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
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
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
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
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
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
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
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
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
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
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
|
-
|
|
147
|
-
|
|
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
|
-
|
|
150
|
-
|
|
151
|
-
|
|
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
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
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
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
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
|
-
|
|
165
|
-
|
|
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.
|
|
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.
|
|
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:
|
|
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
|
-
|
|
164
|
-
|
|
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
|