browser 5.3.1 → 6.2.0

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.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/{FUNDING.yml → .github/FUNDING.yml} +2 -1
  3. data/.github/workflows/{tests.yml → ruby-tests.yml} +17 -17
  4. data/.rubocop.yml +3 -23
  5. data/CHANGELOG.md +23 -7
  6. data/LICENSE.md +20 -0
  7. data/README.md +12 -4
  8. data/bots.yml +23 -0
  9. data/browser.gemspec +5 -5
  10. data/gemfiles/{rails6_0.gemfile → 7_0.gemfile} +1 -1
  11. data/gemfiles/{rails6_1.gemfile → 7_1.gemfile} +1 -1
  12. data/lib/browser/accept_language.rb +1 -1
  13. data/lib/browser/base.rb +39 -29
  14. data/lib/browser/browser.rb +25 -20
  15. data/lib/browser/chrome.rb +4 -0
  16. data/lib/browser/device.rb +10 -10
  17. data/lib/browser/edge.rb +1 -1
  18. data/lib/browser/epiphany.rb +21 -0
  19. data/lib/browser/meta/base.rb +1 -1
  20. data/lib/browser/platform/ios.rb +1 -1
  21. data/lib/browser/platform.rb +1 -1
  22. data/lib/browser/safari.rb +1 -0
  23. data/lib/browser/testing.rb +3 -3
  24. data/lib/browser/version.rb +1 -1
  25. data/lib/browser.rb +1 -1
  26. data/search_engines.yml +1 -0
  27. data/test/browser_test.rb +3 -3
  28. data/test/rails_test.rb +1 -1
  29. data/test/sample_app.rb +2 -2
  30. data/test/test_helper.rb +4 -2
  31. data/test/ua.yml +11 -4
  32. data/test/ua_bots.yml +18 -0
  33. data/test/unit/accept_language_test.rb +1 -1
  34. data/test/unit/android_app_test.rb +3 -3
  35. data/test/unit/android_test.rb +17 -17
  36. data/test/unit/blackberry_test.rb +1 -1
  37. data/test/unit/bots_test.rb +15 -4
  38. data/test/unit/chrome_test.rb +7 -0
  39. data/test/unit/device_test.rb +25 -25
  40. data/test/unit/edge_test.rb +6 -0
  41. data/test/unit/electron_test.rb +1 -1
  42. data/test/unit/epiphany_test.rb +21 -0
  43. data/test/unit/facebook_test.rb +3 -3
  44. data/test/unit/generic_test.rb +3 -3
  45. data/test/unit/instagram_test.rb +2 -2
  46. data/test/unit/internet_explorer_test.rb +18 -18
  47. data/test/unit/ios_app_test.rb +3 -3
  48. data/test/unit/ios_test.rb +18 -12
  49. data/test/unit/kindle_test.rb +15 -0
  50. data/test/unit/meta_test.rb +13 -13
  51. data/test/unit/platform_test.rb +33 -25
  52. data/test/unit/proxy_test.rb +2 -2
  53. data/test/unit/safari_test.rb +14 -9
  54. data/test/unit/snapchat_test.rb +3 -3
  55. data/test/unit/uc_browser_test.rb +1 -1
  56. data/test/unit/windows_test.rb +11 -11
  57. metadata +15 -77
@@ -96,7 +96,7 @@ module Browser
96
96
  def ipod_touch?
97
97
  id == :ipod_touch
98
98
  end
99
- alias_method :ipod?, :ipod_touch?
99
+ alias ipod? ipod_touch?
100
100
 
101
101
  def iphone?
102
102
  id == :iphone
@@ -105,12 +105,12 @@ module Browser
105
105
  def ps3?
106
106
  id == :ps3
107
107
  end
108
- alias_method :playstation3?, :ps3?
108
+ alias playstation3? ps3?
109
109
 
110
110
  def ps4?
111
111
  id == :ps4
112
112
  end
113
- alias_method :playstation4?, :ps4?
113
+ alias playstation4? ps4?
114
114
 
115
115
  def psp?
116
116
  id == :psp
@@ -119,8 +119,8 @@ module Browser
119
119
  def playstation_vita?
120
120
  id == :psvita
121
121
  end
122
- alias_method :vita?, :playstation_vita?
123
- alias_method :psp_vita?, :playstation_vita?
122
+ alias vita? playstation_vita?
123
+ alias psp_vita? playstation_vita?
124
124
 
125
125
  def kindle?
126
126
  id == :kindle || kindle_fire?
@@ -133,22 +133,22 @@ module Browser
133
133
  def nintendo_wii?
134
134
  id == :wii
135
135
  end
136
- alias_method :wii?, :nintendo_wii?
136
+ alias wii? nintendo_wii?
137
137
 
138
138
  def nintendo_wiiu?
139
139
  id == :wiiu
140
140
  end
141
- alias_method :wiiu?, :nintendo_wiiu?
141
+ alias wiiu? nintendo_wiiu?
142
142
 
143
143
  def nintendo_switch?
144
144
  id == :switch
145
145
  end
146
- alias_method :switch?, :nintendo_switch?
146
+ alias switch? nintendo_switch?
147
147
 
148
148
  def blackberry_playbook?
149
149
  id == :playbook
150
150
  end
151
- alias_method :playbook?, :blackberry_playbook?
151
+ alias playbook? blackberry_playbook?
152
152
 
153
153
  def surface?
154
154
  id == :surface
@@ -202,7 +202,7 @@ module Browser
202
202
  # rubocop:disable Layout/LineLength
203
203
  private def detect_mobile?
204
204
  psp? ||
205
- /zunewp7/i.match?(ua) ||
205
+ /zunewp7|crios/i.match?(ua) ||
206
206
  %r{(android|bb\d+|meego).+mobile|avantgo|bada/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino}i.match(ua) ||
207
207
  %r{1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw-(n|u)|c55/|capi|ccwa|cdm-|cell|chtm|cldc|cmd-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc-s|devi|dica|dmob|do(c|p)o|ds(12|-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(-|_)|g1 u|g560|gene|gf-5|g-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd-(m|p|t)|hei-|hi(pt|ta)|hp( i|ip)|hs-c|ht(c(-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i-(20|go|ma)|i230|iac( |-|/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |/)|klon|kpt |kwc-|kyo(c|k)|le(no|xi)|lg( g|/(k|l|u)|50|54|-[a-w])|libw|lynx|m1-w|m3ga|m50/|ma(te|ui|xo)|mc(01|21|ca)|m-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|-([1-8]|c))|phil|pire|pl(ay|uc)|pn-2|po(ck|rt|se)|prox|psio|pt-g|qa-a|qc(07|12|21|32|60|-[2-7]|i-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55/|sa(ge|ma|mm|ms|ny|va)|sc(01|h-|oo|p-)|sdk/|se(c(-|0|1)|47|mc|nd|ri)|sgh-|shar|sie(-|m)|sk-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h-|v-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl-|tdg-|tel(i|m)|tim-|t-mo|to(pl|sh)|ts(70|m-|m3|m5)|tx-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas-|your|zeto|zte-}i.match?(ua[0..3])
208
208
  end
data/lib/browser/edge.rb CHANGED
@@ -18,7 +18,7 @@ module Browser
18
18
  ua.match?(%r{((?:Edge|Edg|EdgiOS|EdgA)/[\d.]+|Trident/8)})
19
19
  end
20
20
 
21
- def chrome_based?
21
+ def chromium_based?
22
22
  match? && ua.match?(/\bEdg\b/)
23
23
  end
24
24
  end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Browser
4
+ class Epiphany < Base
5
+ def id
6
+ :epiphany
7
+ end
8
+
9
+ def name
10
+ "Epiphany"
11
+ end
12
+
13
+ def full_version
14
+ ua[%r{Epiphany/([\d.]+)}, 1] || "0.0"
15
+ end
16
+
17
+ def match?
18
+ ua.include?("Epiphany")
19
+ end
20
+ end
21
+ end
@@ -37,7 +37,7 @@ module Browser
37
37
  end
38
38
 
39
39
  def to_a
40
- meta.to_s.squeeze(" ").split(" ")
40
+ meta.to_s.squeeze(" ").split
41
41
  end
42
42
  end
43
43
  end
@@ -3,7 +3,7 @@
3
3
  module Browser
4
4
  class Platform
5
5
  class IOS < Base
6
- MATCHER = /(iPhone|iPad|iPod)/.freeze
6
+ MATCHER = /(iPhone|iPad|iPod|CriOS)/.freeze
7
7
  VERSION_MATCHER =
8
8
  /OS (?<major>\d+)_(?<minor>\d+)_?(?<patch>\d+)?/.freeze
9
9
 
@@ -138,7 +138,7 @@ module Browser
138
138
  def android_app?
139
139
  android? && ua.match?(/\bwv\b/)
140
140
  end
141
- alias_method :android_webview?, :android_app?
141
+ alias android_webview? android_app?
142
142
 
143
143
  # http://msdn.microsoft.com/fr-FR/library/ms537503.aspx#PltToken
144
144
  def windows_xp?
@@ -19,6 +19,7 @@ module Browser
19
19
 
20
20
  def match?
21
21
  ua.include?("Safari") &&
22
+ !platform.linux? &&
22
23
  !ua.match?(/PhantomJS|FxiOS/) &&
23
24
  !edge? &&
24
25
  !chrome? &&
@@ -16,9 +16,9 @@ module Browser
16
16
  end
17
17
 
18
18
  def self.search_engine_user_agents
19
- @search_engine_user_agents ||= begin
20
- YAML.load_file(Browser.root.join("test/ua_search_engines.yml"))
21
- end
19
+ @search_engine_user_agents ||= YAML.load_file(
20
+ Browser.root.join("test/ua_search_engines.yml")
21
+ )
22
22
  end
23
23
 
24
24
  def self.[](key)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Browser
4
- VERSION = "5.3.1"
4
+ VERSION = "6.2.0"
5
5
  end
data/lib/browser.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "browser/browser"
4
- require_relative "browser/rails" if defined?(::Rails)
4
+ require_relative "browser/rails" if defined?(Rails)
data/search_engines.yml CHANGED
@@ -1,3 +1,4 @@
1
+ ---
1
2
  ask jeeves: "Ask Jeeves"
2
3
  baidu: "Chinese search engine"
3
4
  bingbot: "Microsoft bing bot"
data/test/browser_test.rb CHANGED
@@ -8,7 +8,7 @@ class BrowserTest < Minitest::Test
8
8
  assert_equal "Safari", browser.ua
9
9
  end
10
10
 
11
- test "don't fail with nil user agent" do
11
+ test "does not fail with nil user agent" do
12
12
  browser = Browser.new(nil)
13
13
  refute browser.known?
14
14
  end
@@ -25,7 +25,7 @@ class BrowserTest < Minitest::Test
25
25
  Safari
26
26
  UCBrowser
27
27
  ].each do |ua|
28
- test "don't fail when have no version info (#{ua})" do
28
+ test "does not fail when have no version info (#{ua})" do
29
29
  browser = Browser.new(ua)
30
30
  assert_equal "0", browser.version
31
31
  assert_equal "0.0", browser.full_version
@@ -117,7 +117,7 @@ class BrowserTest < Minitest::Test
117
117
 
118
118
  test "returns empty language set for missing accept language" do
119
119
  browser = Browser.new("")
120
- assert_equal [], browser.accept_language
120
+ assert_empty browser.accept_language
121
121
  end
122
122
 
123
123
  test "sets accept language while instantiating object" do
data/test/rails_test.rb CHANGED
@@ -26,7 +26,7 @@ class RailsTest < Minitest::Test
26
26
  "HTTP_ACCEPT_LANGUAGE" => "en-US;q=0.8"
27
27
 
28
28
  assert_equal 200, last_response.status
29
- assert_equal true, JSON.parse(last_response.body)["isBot"]
29
+ assert JSON.parse(last_response.body)["isBot"]
30
30
  assert_equal "en-US", JSON.parse(last_response.body)["acceptLanguages"][0]
31
31
  end
32
32
  end
data/test/sample_app.rb CHANGED
@@ -9,7 +9,7 @@ class PagesController < ActionController::Base
9
9
  end
10
10
  end
11
11
 
12
- class PotsController < ActionController::API
12
+ class BotsController < ActionController::API
13
13
  def index
14
14
  render json: {
15
15
  isBot: browser.bot?,
@@ -42,7 +42,7 @@ class SampleApp < Rails::Application
42
42
 
43
43
  get "/home", to: "pages#home"
44
44
 
45
- get "/api/pages", to: "pots#index"
45
+ get "/api/pages", to: "bots#index"
46
46
  end
47
47
 
48
48
  config.middleware.use Browser::Middleware do
data/test/test_helper.rb CHANGED
@@ -1,7 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "simplecov"
4
- SimpleCov.start
4
+ SimpleCov.start do
5
+ add_filter %r{/test/}
6
+ end
5
7
 
6
8
  ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
7
9
  require "bundler/setup"
@@ -14,7 +16,7 @@ require "yaml"
14
16
  module Minitest
15
17
  class Test
16
18
  setup do
17
- Browser::Bot.instance_variable_set("@detect_empty_ua", false)
19
+ Browser::Bot.instance_variable_set(:@detect_empty_ua, false)
18
20
  end
19
21
 
20
22
  def assert_deprecated(message, file, line, &block)
data/test/ua.yml CHANGED
@@ -30,11 +30,13 @@ BLACKBERRY7: "Mozilla/5.0 (BlackBerry; U; BlackBerry AAAA; en-US) AppleWebKit/53
30
30
  BLACKBERRY: "BlackBerry7100i/4.1.0 Profile/MIDP-2.0 Configuration/CLDC-1.1 VendorID/103"
31
31
  CHROME: "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_4; en-US) AppleWebKit/533.4 (KHTML, like Gecko) Chrome/5.0.375.99 Safari/533.4"
32
32
  CHROME_OS: "Mozilla/5.0 (X11; CrOS x86_64 3701.81.0) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.57 Safari/537.31."
33
+ CHROME_REQUEST_DESKTOP_SITE: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/130 Version/11.1.1 Safari/605.1.15"
33
34
  COREMEDIA: "Apple Mac OS X v10.6.4 CoreMedia v1.0.0.10F569"
34
35
  CUSTOM_APP: "Our App 0.0.1 (Linux; Android 4.0.3; HTC Ruby Build/IML74K; en_CA)"
35
36
  DUCKDUCKGO_BROWSER_ANDROID: Mozilla/5.0 (Linux; Android 10) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.96 Mobile Safari/537.36 DuckDuckGo/5"
36
37
  DUCKDUCKGO_BROWSER_IOS: "Mozilla/5.0 (iPhone; CPU iPhone OS 13_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 DuckDuckGo/7"
37
38
  ELECTRON: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Electron/1.4.12 Safari/537.36"
39
+ EPIPHANY: "Mozilla/5.0 (X11; Ubuntu; Linux x86_64) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/11.0 Safari/605.1.15 Ubuntu/16.04 (3.18.11-0ubuntu1) Epiphany/3.18.11"
38
40
  FACEBOOK: Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_3 like Mac OS X) AppleWebKit/603.3.8 (KHTML, like Gecko) Mobile/14G60 [FBAN/FBIOS;FBAV/135.0.0.45.90;FBBV/66877072;FBDV/iPhone9,3;FBMD/iPhone;FBSN/iOS;FBSV/10.3.3;FBSS/2;FBCR/AT&T;FBID/phone;FBLC/en_US;FBOP/5;FBRV/0]
39
41
  FACEBOOK_ANDROID: "Mozilla/5.0 (Linux; Android 9; ONEPLUS A6003 Build/PKQ1.180716.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/73.0.3683.90 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/214.0.0.43.83;]"
40
42
  FACEBOOK_IOS: "Mozilla/5.0 (iPhone; CPU iPhone OS 12_1_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/16D57 [FBAN/FBIOS;FBDV/iPhone11,2;FBMD/iPhone;FBSN/iOS;FBSV/12.1.4;FBSS/3;FBCR/KPN NL;FBID/phone;FBLC/en_GB;FBOP/5]"
@@ -83,6 +85,11 @@ KINDLE: "Mozilla/5.0 (Linux; U; en-US) AppleWebKit/528.5+ (KHTML, like Gecko, Sa
83
85
  KINDLE_FIRE: "Mozilla/5.0 (Linux; U; Android 2.3.4; en-us; Kindle Fire Build/GINGERBREAD) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1"
84
86
  KINDLE_FIRE_HD: "Mozilla/5.0 (Linux; U; en-us; KFTT Build/IML74K) AppleWebKit/535.19 (KHTML, like Gecko) Silk/3.4 Safari/535.19 Silk-Accelerated=true"
85
87
  KINDLE_FIRE_HD_MOBILE: "Mozilla/5.0 (Linux; U; Android 4.0.3; en-us; KFTT Build/IML74K) AppleWebKit/535.19 (KHTML, like Gecko) Silk/3.4 Mobile Safari/535.19 Silk-Accelerated=true"
88
+ KINDLE_SILK_DESKTOP: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Silk/44.1.54 like Chrome/44.0.2403.63 Safari/537.36
89
+ KINDLE_SILK_MOBILE: Mozilla/5.0 (Linux; U; Android 4.4.3; KFTHWI Build/KTU84M) AppleWebKit/537.36 (KHTML, like Gecko) Silk/44.1.54 like Chrome/44.0.2403.63 Mobile Safari/537.36
90
+ KINDLE_SILK_MOBILE_1ST_GEN: Mozilla/5.0 (Linux; U; Android 2.3.4; en-us; Silk/1.0.13.81_10003810) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1 Silk-Accelerated=true
91
+ KINDLE_SILK_TABLET: Mozilla/5.0 (Linux; Android 4.4.3; KFTHWI Build/KTU84M) AppleWebKit/537.36 (KHTML, like Gecko) Silk/44.1.54 like Chrome/44.0.2403.63 Safari/537.36
92
+ KINDLE_SILK_TABLET_1ST_GEN: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_3; en-us; Silk/1.0.13.81_10003810) AppleWebKit/533.16 (KHTML, like Gecko) Version/5.0 Safari/533.16 Silk-Accelerated=true
86
93
  LUMIA800: "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0; XBLWP7; ZuneWP7"
87
94
  MAC_OS: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.5 Safari/605.1.15"
88
95
  MAC_OSX: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_2) AppleWebKit/601.3.9 (KHTML, like Gecko) Version/9.0.2 Safari/601.3.9"
@@ -122,8 +129,6 @@ QQ_BROWSER_ANDROID: "Mozilla/5.0 (Linux; Android 5.1.1; SM-N9108V Build/LMY47X)
122
129
  QQ_BROWSER_IOS: "Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Mobile/13E238 QQ/6.3.3.432 V1_IPH_SQ_6.3.3_1_APP_A Pixel/640 Core/UIWebView NetType/WIFI Mem/47"
123
130
  QQ_BROWSER_MAC: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.98 Safari/537.36 QQBrowser/4.2.4753.400"
124
131
  QQ_BROWSER_MAC_LITE: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/602.2.14 (KHTML, like Gecko) Version/10.0.1 Safari/602.2.14 QQBrowserLite/1.0.4"
125
- SOUGOU_BROWSER: "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.81 Safari/537.36 SE 2.X MetaSr 1.0"
126
- SOUGOU_BROWSER_MOBILE: "Mozilla/5.0 (Linux; Android 7.1.2; Redmi 4X Build/N2G47H; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/68.0.3440.106 Mobile Safari/537.36 AWP/2.0 SogouMSE,SogouMobileBrowser/5.28.12"
127
132
  QUICKTIME: "QuickTime/7.6.8 (qtver=7.6.8;os=Windows NT 5.1Service Pack 3)"
128
133
  SAFARI3: "Mozilla/5.0 (Windows; U; Windows NT 6.0; en) AppleWebKit/522.15.5 (KHTML, like Gecko) Version/3.0.3 Safari/522.15.5"
129
134
  SAFARI4: "Mozilla/5.0 (Windows; U; Windows NT 6.0; fr-ch) AppleWebKit/531.9 (KHTML, like Gecko) Version/4.0.3 Safari/531.9"
@@ -138,14 +143,16 @@ SAFARI_IPHONE_WEBAPP_MODE: "Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_2 like Mac O
138
143
  SAMSUNG: "Mozilla/5.0 (Linux; U; Android 4.0.4; en-us; SAMSUNG-SGH-I497 Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Safari/534.30"
139
144
  SAMSUNG_BROWSER: "Mozilla/5.0 (Linux; Android 10; SAMSUNG SM-N960U) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/11.1 Chrome/75.0.3770.143 Mobile Safari/537.36"
140
145
  SAMSUNG_CHROME: "Mozilla/5.0 (Linux; Android 4.4.2; en-gb; SAMSUNG GT-I9195/I9195XXUCNEA Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Version/1.5 Chrome/28.0.1500.94 Mobile Safari/537.36"
141
- SAMSUNG_SM-G975F: "Mozilla/5.0 (Linux; Android 10; SM-G975F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.101 Mobile Safari/537.36"
142
- SAMSUNG_SM-G960F: "Mozilla/5.0 (Linux; Android 8.0.0; SM-G960F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.127 Mobile Safari/537.36"
143
146
  SAMSUNG_SM-F700F: "Mozilla/5.0 (Linux; Android 10; SAMSUNG SM-F700F) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/11.1 Chrome/75.0.3770.143 Mobile Safari/537.36"
144
147
  SAMSUNG_SM-FAKE: "Mozilla/5.0 (Linux; Android 8.0.0; SM-0000) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.127 Mobile Safari/537.36"
148
+ SAMSUNG_SM-G960F: "Mozilla/5.0 (Linux; Android 8.0.0; SM-G960F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.127 Mobile Safari/537.36"
149
+ SAMSUNG_SM-G975F: "Mozilla/5.0 (Linux; Android 10; SM-G975F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.101 Mobile Safari/537.36"
145
150
  SMART_TV: "Mozilla/5.0 (SmartHub; SMART-TV; U; Linux/SmartTV) AppleWebKit/531.2+ (KHTML, like Gecko) WebBrowser/1.0 SmartTV Safari/531.2+"
146
151
  SNAPCHAT: Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Snapchat/10.69.5.72 (iPhone10,3; iOS 13.2.2; gzip)
147
152
  SNAPCHAT_EMPTY_STRING_VERSION: "Mozilla/5.0 (Linux; Android 9; SM-N960U Build/PPR1.180610.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.96 Mobile Safari/537.36Snapchat10.70.0.0 (SM-N960U; Android 9#N960USQS3CSJ2#28; gzip)"
148
153
  SNAPCHAT_SPACE_VERSION: "Mozilla/5.0 (Linux; Android 9; SM-N960U Build/PPR1.180610.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.96 Mobile Safari/537.36Snapchat 10.70.0.0 (SM-N960U; Android 9#N960USQS3CSJ2#28; gzip)"
154
+ SOUGOU_BROWSER: "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.81 Safari/537.36 SE 2.X MetaSr 1.0"
155
+ SOUGOU_BROWSER_MOBILE: "Mozilla/5.0 (Linux; Android 7.1.2; Redmi 4X Build/N2G47H; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/68.0.3440.106 Mobile Safari/537.36 AWP/2.0 SogouMSE,SogouMobileBrowser/5.28.12"
149
156
  SPUTNIK: "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 SputnikBrowser/4.1.2801.0 Safari/537.36"
150
157
  SURFACE: "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; ARM; Trident/6.0; Touch)"
151
158
  SYMBIAN: "Nokia5250/10.0.011 (SymbianOS/9.4; U; Series60/5.0 Mozilla/5.0; Profile/MIDP-2.1 Configuration/CLDC-1.1 ) AppleWebKit/525 (KHTML, like Gecko) Safari/525 3gpp-gba"
data/test/ua_bots.yml CHANGED
@@ -1,9 +1,13 @@
1
1
  ---
2
2
  ADLXBOT: "Mozilla/5.0 (compatible; adidxbot/2.0; +http://www.bing.com/bingbot.htm)"
3
3
  ADS_TXT_CRAWLER: "AdsTxtCrawler/1.0"
4
+ AMAZONBOT: Amazonbot
4
5
  ANDERSPINK: "Mozilla/5.0 (compatible; AndersPinkBot/1.0; +http://anderspink.com/bot.html)"
6
+ ANTHROPIC_AI: anthropic-ai
5
7
  APIS_GOOGLE: "APIs-Google; (+https://developers.google.com/webmasters/APIs-Google.html)"
6
8
  APPLE_BOT: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/600.2.5 (KHTML, like Gecko) Version/8.0.2 Safari/600.2.5 (Applebot/0.1)"
9
+ APPLEBOT: Applebot
10
+ APPSIGNALBOT: "AppSignalBot/1.0 (+https://appsignal.com)"
7
11
  ARCHIVEBOT: "ArchiveTeam ArchiveBot/20190617.01 (wpull 2.0.3) and not Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.90 Safari/537.36"
8
12
  ASK: "Mozilla/2.0 (compatible; Ask Jeeves/Teoma; +http://sp.ask.com/docs/about/tech_crawling.html)"
9
13
  AWS_ELB: ELB-HealthChecker/1.0
@@ -13,25 +17,35 @@ BINGBOT: "Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm
13
17
  BINGPREVIEW: "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534+ (KHTML, like Gecko) BingPreview/1.0b"
14
18
  BUBING: "BUbiNG (+http://law.di.unimi.it/BUbiNG.html)"
15
19
  BUZZBOT: "Buzzbot/1.0 (Buzzbot; http://www.buzzstream.com; buzzbot@buzzstream.com)"
20
+ BYTESPIDER: Bytespider
21
+ CCBOT: CCBot
22
+ CHATGPT_USER: ChatGPT-User
23
+ CHECKLY: "Checkly/1.0 (https://www.checklyhq.com)"
16
24
  CHROME_LIGHTHOUSE: "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3694.0 Mobile Safari/537.36 Chrome-Lighthouse"
17
25
  CIPACRAWLER: "CipaCrawler/3.0 (info@domaincrawler.com; http://www.domaincrawler.com/www.example.com)"
26
+ CLAUDE_WEB: Claude-Web
27
+ CLAUDEBOT: ClaudeBot
18
28
  CLOUDFLARE: "Mozilla/5.0 (compatible; CloudFlare-AlwaysOnline/1.0; +http://www.cloudflare.com/always-online) AppleWebKit/534.34"
29
+ COHERE-AI: cohere-ai
19
30
  COMMONCRAWL: "CCBot/2.0 (http://commoncrawl.org/faq/)"
20
31
  COMODO_SSL_CHECKER: "COMODO SSL Checker"
21
32
  COPYPANTS: "Mozilla/5.0 (compatible; BotPants/1.0; Linux; +info@copypants.com) KHTML/3.5.5 (like Gecko)"
22
33
  DATAFEEDWATCH: "Datafeedwatch/2.1.x"
23
34
  DATANYZE: "Mozilla/5.0 (X11; Datanyze; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36"
24
35
  DAUMOA: "Mozilla/5.0 (compatible; MSIE or Firefox mutant; not on Windows server;) Daumoa 4.0"
36
+ DIFFBOT: Diffbot
25
37
  DOMAINAREANIMATOR: "Domain Re-Animator Bot (http://domainreanimator.com) - support@domainreanimator.com"
26
38
  DOT_BOT: "Mozilla/5.0 (compatible; DotBot/1.1; http://www.opensiteexplorer.org/dotbot, help@moz.com)"
27
39
  DUCKDUCKGO: "DuckDuckBot/1.0; (+http://duckduckgo.com/duckduckbot.html)"
28
40
  EZPUBLISH: "eZ Publish Link Validator"
29
41
  FACEBOOK_BOT: "facebookexternalhit/1.1 (+http://www.facebook.com/externalhit_uatext.php)"
42
+ FACEBOOKBOT: FacebookBot
30
43
  FYREBOT: "Fyrebot/1.0"
31
44
  GARLIK: "GarlikCrawler/1.2 (http://garlik.com/, crawler@garlik.com)"
32
45
  GERMCRAWLER: "GermCrawler"
33
46
  GO_1.1_PACKAGE_HTTP: "Go 1.1 package http"
34
47
  GO_HTTP_CLIENT: "Go-http-client"
48
+ GOOGLE-EXTENDED: Google-Extended
35
49
  GOOGLE_BOT: "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"
36
50
  GOOGLE_IMAGE_PROXY: "Mozilla/5.0 (Windows NT 5.1; rv:11.0) Gecko Firefox/11.0 (via ggpht.com GoogleImageProxy)"
37
51
  GOOGLE_PAGE_SPEED_INSIGHTS: "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.4 (KHTML, like Gecko; Google Page Speed Insights) Chrome/22.0.1229 Safari/537.4"
@@ -40,6 +54,7 @@ GOOGLE_SITE_VERIFICATION: Mozilla/5.0 (compatible; Google-Site-Verification/1.0)
40
54
  GOOGLE_STACKDRIVER_UPTIME_CHECKS: "GoogleStackdriverMonitoring-UptimeChecks"
41
55
  GOOGLE_STRUCTURED_DATA_TESTING_TOOL2: "Mozilla/5.0 (compatible; Google-Structured-Data-Testing-Tool +http://developers.google.com/structured-data/testing-tool/)"
42
56
  GOOGLE_STRUCTURED_DATA_TESTING_TOOL: "Mozilla/5.0 (compatible; X11; Linux x86_64; Google-StructuredDataTestingTool; +http://www.google.com/webmasters/tools/richsnippets)"
57
+ GPTBOT: GPTBot
43
58
  GRAPESHOT: "Mozilla/5.0 (compatible; GrapeshotCrawler/2.0; +http://www.grapeshot.co.uk/crawler.php)"
44
59
  HTTRACK: "Mozilla/4.5 (compatible; HTTrack 3.0x; Windows 98)"
45
60
  IMPLISENSEBOT: "ImplisenseBot 1.0"
@@ -61,7 +76,9 @@ MSNBOT_MEDIA: "msnbot-media/1.1 (+http://search.msn.com/msnbot.htm)"
61
76
  NETCRAFT2: Netcraft SSL Server Survey - contact info@netcraft.com
62
77
  NETCRAFT: Mozilla/5.0 (compatible; NetcraftSurveyAgent/1.0; +info@netcraft.com)
63
78
  NEWRELICPINGER: NewRelicPinger/1.0 (12345)
79
+ OMGILI: omgili
64
80
  PAESSLER: Mozilla/5.0 (compatible; PRTG Network Monitor (www.paessler.com); Windows)
81
+ PERPLEXITYBOT: PerplexityBot
65
82
  PR-CY_RU: Mozilla/5.0 (compatible; PR-CY.RU; + https://a.pr-cy.ru)
66
83
  PRIVACYAWAREBOT: "Mozilla/5.0 (compatible; PrivacyAwareBot/1.1; +http://www.privacyaware.org)"
67
84
  PROXIMIC: "Mozilla/5.0 (compatible; proximic; +http://www.proximic.com/info/spider.php)"
@@ -98,6 +115,7 @@ YAHOO_SLURP: "Mozilla/5.0 (compatible; Yahoo! Slurp; http://help.yahoo.com/help/
98
115
  YANDEX_DIRECT: "Mozilla/5.0 (compatible; YandexDirect/3.0; +http://yandex.com/bots)"
99
116
  YANDEX_METRIKA: "Mozilla/5.0 (compatible; YandexMetrika/3.0; +http://yandex.com/bots)"
100
117
  YANGA: "Yanga WorldSearch Bot v1.1/beta (http://www.yanga.co.uk/)"
118
+ YOUBOT: YouBot
101
119
  ZABBIX: "Zabbix"
102
120
  ZOOMBOT: "ZoomBot (Linkbot 1.0 http://suite.seozoom.it/bot.html)"
103
121
  ZOOMINFOBOT: "ZoominfoBot (zoominfobot at zoominfo dot com)"
@@ -161,6 +161,6 @@ class AcceptLanguageTest < Minitest::Test
161
161
  test "sets default quality value for invalid strings" do
162
162
  result = Browser::AcceptLanguage.parse(";q=0.0.0.0")
163
163
 
164
- assert_equal 0.1, result[0].quality
164
+ assert_equal 0.1, result[0].quality # rubocop:disable Minitest/AssertInDelta
165
165
  end
166
166
  end
@@ -5,15 +5,15 @@ require "test_helper"
5
5
  class AndroidAppTest < Minitest::Test
6
6
  let(:browser) { Browser.new(Browser["ANDROID_WEBVIEW"]) }
7
7
 
8
- test "detect as android" do
8
+ test "detects as android" do
9
9
  assert browser.platform.android?
10
10
  end
11
11
 
12
- test "detect as webview" do
12
+ test "detects as webview" do
13
13
  assert browser.platform.android_webview?
14
14
  end
15
15
 
16
- test "non-webviews do not detect as webview" do
16
+ test "does not detect non-webviews as webview" do
17
17
  %w[
18
18
  ANDROID_CUPCAKE
19
19
  ANDROID_DONUT
@@ -3,102 +3,102 @@
3
3
  require "test_helper"
4
4
 
5
5
  class AndroidTest < Minitest::Test
6
- test "detect android cupcake (1.5)" do
6
+ test "detects android cupcake (1.5)" do
7
7
  browser = Browser.new(Browser["ANDROID_CUPCAKE"])
8
8
  assert browser.platform.android?
9
9
  assert browser.platform.android?(1.5)
10
10
  end
11
11
 
12
- test "detect android donut (1.6)" do
12
+ test "detects android donut (1.6)" do
13
13
  browser = Browser.new(Browser["ANDROID_DONUT"])
14
14
  assert browser.platform.android?
15
15
  assert browser.platform.android?(1.6)
16
16
  end
17
17
 
18
- test "detect android eclair (2.1)" do
18
+ test "detects android eclair (2.1)" do
19
19
  browser = Browser.new(Browser["ANDROID_ECLAIR_21"])
20
20
  assert browser.platform.android?
21
21
  assert browser.platform.android?(2.1)
22
22
  end
23
23
 
24
- test "detect android froyo (2.2)" do
24
+ test "detects android froyo (2.2)" do
25
25
  browser = Browser.new(Browser["ANDROID_FROYO"])
26
26
  assert browser.platform.android?
27
27
  assert browser.platform.android?(2.2)
28
28
  end
29
29
 
30
- test "detect android gingerbread (2.3)" do
30
+ test "detects android gingerbread (2.3)" do
31
31
  browser = Browser.new(Browser["ANDROID_GINGERBREAD"])
32
32
  assert browser.platform.android?
33
33
  assert browser.platform.android?("~> 2.3.0")
34
34
  end
35
35
 
36
- test "detect android honeycomb (3.0)" do
36
+ test "detects android honeycomb (3.0)" do
37
37
  browser = Browser.new(Browser["ANDROID_HONEYCOMB_30"])
38
38
  assert browser.platform.android?
39
39
  assert browser.platform.android?("~> 3.0")
40
40
  end
41
41
 
42
- test "detect android ice cream sandwich (4.0)" do
42
+ test "detects android ice cream sandwich (4.0)" do
43
43
  browser = Browser.new(Browser["ANDROID_ICECREAM"])
44
44
  assert browser.platform.android?
45
45
  assert browser.platform.android?("~> 4.0")
46
46
  end
47
47
 
48
- test "detect android jellybean (4.1)" do
48
+ test "detects android jellybean (4.1)" do
49
49
  browser = Browser.new(Browser["ANDROID_JELLYBEAN_41"])
50
50
  assert browser.platform.android?
51
51
  assert browser.platform.android?("~> 4.1")
52
52
  end
53
53
 
54
- test "detect android jellybean (4.2)" do
54
+ test "detects android jellybean (4.2)" do
55
55
  browser = Browser.new(Browser["ANDROID_JELLYBEAN_42"])
56
56
  assert browser.platform.android?
57
57
  assert browser.platform.android?(4.2)
58
58
  end
59
59
 
60
- test "detect android jellybean (4.3)" do
60
+ test "detects android jellybean (4.3)" do
61
61
  browser = Browser.new(Browser["ANDROID_JELLYBEAN_43"])
62
62
  assert browser.platform.android?
63
63
  assert browser.platform.android?(4.3)
64
64
  end
65
65
 
66
- test "detect android kitkat (4.4)" do
66
+ test "detects android kitkat (4.4)" do
67
67
  browser = Browser.new(Browser["ANDROID_KITKAT"])
68
68
  assert browser.platform.android?
69
69
  assert browser.platform.android?(4.4)
70
70
  end
71
71
 
72
- test "detect android lollipop (5.0)" do
72
+ test "detects android lollipop (5.0)" do
73
73
  browser = Browser.new(Browser["ANDROID_LOLLIPOP_50"])
74
74
  assert browser.platform.android?
75
75
  assert browser.platform.android?(5.0)
76
76
  end
77
77
 
78
- test "detect android lollipop (5.1)" do
78
+ test "detects android lollipop (5.1)" do
79
79
  browser = Browser.new(Browser["ANDROID_LOLLIPOP_51"])
80
80
  assert browser.platform.android?
81
81
  assert browser.platform.android?(5.1)
82
82
  end
83
83
 
84
- test "detect android oreo (8.0)" do
84
+ test "detects android oreo (8.0)" do
85
85
  browser = Browser.new(Browser["ANDROID_OREO"])
86
86
  assert browser.platform.android?
87
87
  assert browser.platform.android?(8.0)
88
88
  end
89
89
 
90
- test "detect android tv" do
90
+ test "detects android tv" do
91
91
  browser = Browser.new(Browser["ANDROID_TV"])
92
92
  assert browser.platform.android?
93
93
  assert browser.device.tv?
94
94
  end
95
95
 
96
- test "detect nexus player" do
96
+ test "detects nexus player" do
97
97
  browser = Browser.new(Browser["ANDROID_NEXUS_PLAYER"])
98
98
  assert browser.platform.android?
99
99
  end
100
100
 
101
- test "detect firefox for android without android version" do
101
+ test "detects firefox for android without android version" do
102
102
  browser = Browser.new(Browser["FIREFOX_ANDROID"])
103
103
 
104
104
  assert browser.platform.android?
@@ -72,7 +72,7 @@ class BlackberryTest < Minitest::Test
72
72
  assert_equal "7", browser.version
73
73
  end
74
74
 
75
- test "don't detect as two different versions" do
75
+ test "does not detect as two different versions" do
76
76
  browser = Browser.new(Browser["BLACKBERRY10"])
77
77
  assert browser.platform.blackberry?("~> 10.0")
78
78
  refute browser.platform.blackberry?("~> 7.0")
@@ -4,13 +4,13 @@ require "test_helper"
4
4
 
5
5
  class BotsTest < Minitest::Test
6
6
  Browser.bot_user_agents.each do |key, ua|
7
- test "detect #{key} as bot" do
7
+ test "detects #{key} as bot" do
8
8
  browser = Browser.new(ua)
9
9
  assert browser.bot?
10
10
  end
11
11
  end
12
12
 
13
- test "don't detect as bot" do
13
+ test "does not detect as bot" do
14
14
  browser = Browser.new(Browser["CHROME"])
15
15
  refute browser.bot?
16
16
  end
@@ -55,7 +55,7 @@ class BotsTest < Minitest::Test
55
55
  refute browser.safari?
56
56
  end
57
57
 
58
- test "custom android user agent (#144)" do
58
+ test "handles custom android user agent (#144)" do
59
59
  browser = Browser.new(Browser["CUSTOM_APP"])
60
60
 
61
61
  assert browser.platform.android?
@@ -86,7 +86,7 @@ class BotsTest < Minitest::Test
86
86
  end
87
87
 
88
88
  test "adds custom bot matcher" do
89
- Browser::Bot.matchers << ->(ua, _) { ua.match?(/some-script/) }
89
+ Browser::Bot.matchers << ->(ua, _) { ua.include?("some-script") }
90
90
  browser = Browser.new("some-script")
91
91
 
92
92
  assert browser.bot?
@@ -108,4 +108,15 @@ class BotsTest < Minitest::Test
108
108
  assert_equal Browser::Bot::KeywordMatcher, browser.bot.why?
109
109
  end
110
110
  end
111
+
112
+ test "extends lists" do
113
+ Browser::Bot.bots["another-bot"] = "Another bot"
114
+ Browser::Bot.bot_exceptions.push("exclude-this-bot")
115
+ Browser::Bot.search_engines["new-search-engine"] = "New search engine"
116
+
117
+ assert_equal "Another bot", Browser::Bot.bots["another-bot"]
118
+ assert_includes Browser::Bot.bot_exceptions, "exclude-this-bot"
119
+ assert_equal "New search engine",
120
+ Browser::Bot.search_engines["new-search-engine"]
121
+ end
111
122
  end
@@ -12,6 +12,7 @@ class ChromeTest < Minitest::Test
12
12
  assert browser.webkit?
13
13
  assert_equal "5.0.375.99", browser.full_version
14
14
  assert_equal "5", browser.version
15
+ assert browser.chromium_based?
15
16
  end
16
17
 
17
18
  test "detects mobile chrome" do
@@ -25,6 +26,12 @@ class ChromeTest < Minitest::Test
25
26
  assert_equal "19", browser.version
26
27
  end
27
28
 
29
+ test "detects chrome in desktop mode" do
30
+ browser = Browser.new(Browser["CHROME_REQUEST_DESKTOP_SITE"])
31
+ assert browser.chromium_based?
32
+ assert browser.chrome?
33
+ end
34
+
28
35
  test "detects samsung chrome" do
29
36
  browser = Browser.new(Browser["SAMSUNG_CHROME"])
30
37