browser 2.6.1 → 2.7.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: efec89842173ca944eb69503ca1bc3c90740b94d659b15b84ec7bf807d55bbb6
4
- data.tar.gz: b8f3f6cf6ba1f2d75fd4ab9a0a018211af1416099372e90334b649c474e19360
3
+ metadata.gz: 0e06930aa3adaf7fcb64ba7835316a1e621ca68d48b9e7cb628613737e3f2b3c
4
+ data.tar.gz: 63af8472b567a45c2cc9bf7fcab64522772313fa701c155d536de81ae5e4bc06
5
5
  SHA512:
6
- metadata.gz: ca0d06b06a1a737e3fd1da1476a9250ec40d7a870f7b239c429550daf8f035fac11bdd1b084f2300e148f08e8e2ad698e7459224cd07f81aa6008bc5eb6d3664
7
- data.tar.gz: b693d37d72f89a54a9e516a4197dbfece42d6775dfdaf0dc71628c177e12bb7877df24f068f52a6454f5c4bd589603ac39f455c05d5250e43ae670aae82fb116
6
+ metadata.gz: f09b0e90fa5df86138f39f549dab4128ae459066a60eeb22e80ec87edf72b7d228c83115dff7f6e6498c8f98f72660ff2c262341ecd1201eb368c52e5be38134
7
+ data.tar.gz: ddecdb109e863eac0418faaab17b2dbe581fd1d244ab85d3bdbeb6b416b9c20204ef1c39d400c2ac5340cde9960280fc41367e889eee2ef912b819f394ff206c
@@ -1,136 +1,138 @@
1
+ ---
2
+
1
3
  AllCops:
2
4
  Exclude:
3
- - "bin/**/*"
4
- - "gemfiles/**/*"
5
- - "vendor/**/*"
6
- - "Gemfile"
7
- - "Rakefile"
5
+ - bin/**/*
6
+ - gemfiles/**/*
7
+ - vendor/**/*
8
+ - Gemfile
9
+ - Rakefile
8
10
  - "*.gemspec"
9
- - "config.ru"
10
-
11
- Style/Alias:
12
- EnforcedStyle: prefer_alias_method
11
+ - config.ru
13
12
 
14
- Style/FrozenStringLiteralComment:
15
- EnforcedStyle: always
13
+ Layout/DotPosition:
14
+ EnforcedStyle: leading
16
15
 
17
- Style/ClassCheck:
18
- EnforcedStyle: kind_of?
16
+ Layout/RescueEnsureAlignment:
17
+ Enabled: false
19
18
 
20
- Metrics/LineLength:
21
- Max: 80
19
+ Layout/SpaceBeforeBlockBraces:
20
+ EnforcedStyle: space
22
21
 
23
- Style/BlockDelimiters:
24
- Enabled: false
22
+ Layout/SpaceInsideBlockBraces:
23
+ EnforcedStyle: space
24
+ SpaceBeforeBlockParameters: false
25
25
 
26
- Style/RegexpLiteral:
26
+ Layout/SpaceInsideHashLiteralBraces:
27
27
  Enabled: false
28
28
 
29
29
  Metrics/AbcSize:
30
30
  Enabled: false
31
31
 
32
- Style/PerlBackrefs:
32
+ Metrics/ClassLength:
33
33
  Enabled: false
34
34
 
35
- ClassLength:
35
+ Metrics/CyclomaticComplexity:
36
36
  Enabled: false
37
37
 
38
- CyclomaticComplexity:
39
- Enabled: false
38
+ Metrics/LineLength:
39
+ Max: 80
40
40
 
41
- Documentation:
41
+ Metrics/MethodLength:
42
42
  Enabled: false
43
43
 
44
- Encoding:
44
+ Metrics/ParameterLists:
45
45
  Enabled: false
46
46
 
47
- FileName:
47
+ Naming/FileName:
48
48
  Enabled: false
49
49
 
50
- IfUnlessModifier:
50
+ Naming/PredicateName:
51
+ NamePrefixBlacklist:
52
+ - is_
53
+
54
+ Naming/UncommunicativeMethodParamName:
51
55
  Enabled: false
52
56
 
53
- MethodLength:
57
+ Style/Alias:
58
+ EnforcedStyle: prefer_alias_method
59
+
60
+ Style/BlockDelimiters:
54
61
  Enabled: false
55
62
 
56
- ModuleFunction:
63
+ Style/ClassCheck:
64
+ EnforcedStyle: kind_of?
65
+
66
+ Style/CollectionMethods:
67
+ PreferredMethods:
68
+ collect: map
69
+ collect!: map!
70
+ inject: reduce
71
+ detect: find
72
+ find_all: select
73
+
74
+ Style/Documentation:
57
75
  Enabled: false
58
76
 
59
- OneLineConditional:
77
+ Style/DoubleNegation:
60
78
  Enabled: false
61
79
 
62
- ParameterLists:
80
+ Style/Encoding:
63
81
  Enabled: false
64
82
 
65
- Proc:
83
+ Style/FrozenStringLiteralComment:
84
+ EnforcedStyle: always
85
+
86
+ Style/IfUnlessModifier:
66
87
  Enabled: false
67
88
 
68
- SingleLineBlockParams:
89
+ Style/ModuleFunction:
69
90
  Enabled: false
70
91
 
71
- VariableInterpolation:
92
+ Style/OneLineConditional:
72
93
  Enabled: false
73
94
 
74
- Style/TrailingCommaInArrayLiteral:
95
+ Style/PercentLiteralDelimiters:
96
+ PreferredDelimiters:
97
+ "%": "[]"
98
+ "%i": "[]"
99
+ "%q": "[]"
100
+ "%Q": "[]"
101
+ "%r": "[]"
102
+ "%s": "[]"
103
+ "%w": "[]"
104
+ "%W": "[]"
105
+ "%x": "[]"
106
+
107
+ Style/PerlBackrefs:
75
108
  Enabled: false
76
109
 
77
- Style/TrailingCommaInHashLiteral:
110
+ Style/Proc:
78
111
  Enabled: false
79
112
 
80
- WhileUntilModifier:
113
+ Style/RegexpLiteral:
81
114
  Enabled: false
82
115
 
83
- Naming/UncommunicativeMethodParamName:
116
+ Style/SafeNavigation:
84
117
  Enabled: false
85
118
 
86
- PredicateName:
87
- NamePrefixBlacklist:
88
- - is_
119
+ Style/SingleLineBlockParams:
120
+ Enabled: false
89
121
 
90
- StringLiterals:
122
+ Style/StringLiterals:
91
123
  EnforcedStyle: double_quotes
92
124
  SupportedStyles:
93
125
  - single_quotes
94
126
  - double_quotes
95
127
 
96
- DotPosition:
97
- EnforcedStyle: leading
98
-
99
- SpaceBeforeBlockBraces:
100
- EnforcedStyle: space
101
-
102
- DoubleNegation:
128
+ Style/TrailingCommaInArrayLiteral:
103
129
  Enabled: false
104
130
 
105
- SpaceInsideBlockBraces:
106
- EnforcedStyle: space
107
- SpaceBeforeBlockParameters: false
108
-
109
- SpaceInsideHashLiteralBraces:
131
+ Style/TrailingCommaInHashLiteral:
110
132
  Enabled: false
111
133
 
112
- PercentLiteralDelimiters:
113
- PreferredDelimiters:
114
- "%": "[]"
115
- "%i": "[]"
116
- "%q": "[]"
117
- "%Q": "[]"
118
- "%r": "[]"
119
- "%s": "[]"
120
- "%w": "[]"
121
- "%W": "[]"
122
- "%x": "[]"
123
-
124
- Style/CollectionMethods:
125
- PreferredMethods:
126
- collect: "map"
127
- collect!: "map!"
128
- inject: "reduce"
129
- detect: "find"
130
- find_all: "select"
131
-
132
- Style/SafeNavigation:
134
+ Style/VariableInterpolation:
133
135
  Enabled: false
134
136
 
135
- Layout/RescueEnsureAlignment:
137
+ Style/WhileUntilModifier:
136
138
  Enabled: false
@@ -1,13 +1,14 @@
1
+ ---
1
2
  language: ruby
2
3
  sudo: false
3
4
  cache: bundler
4
5
  rvm:
5
6
  - "2.6.0"
6
7
  - "2.5.0"
7
- - "2.4.0"
8
8
  gemfile:
9
9
  - Gemfile
10
10
  - gemfiles/rails5.gemfile
11
+ - gemfiles/rails6.gemfile
11
12
  script: bundle exec rake
12
13
  notifications:
13
14
  email: false
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## Unreleased
4
+
5
+ - Add more Slack bots.
6
+ - Handle instagram user agents that have a slash instead of a space.
7
+ - Add `Browser::Bot.why?(ua)` to help debugging why a user agent is considered bot.
8
+ - Promote Snapchat to a browser (it was detected as a bot previously).
9
+ - Detect Edge based on Chrome correctly.
10
+ - Improve Yandex detection.
11
+ - Add Sputnik (https://browser.sputnik.ru)
12
+ - Detect Android devices.
13
+ - Add ScoutURLMonitor to the bot list.
14
+
3
15
  ## 2.6.1
4
16
 
5
17
  - Also include controller extensions to `ActionController::Base`.
data/Gemfile CHANGED
@@ -1,2 +1,4 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source "http://rubygems.org"
2
4
  gemspec
data/README.md CHANGED
@@ -49,13 +49,16 @@ browser.version # major version number
49
49
  browser.webkit?
50
50
  browser.webkit_full_version
51
51
  browser.yandex?
52
- browser.wechat? # detect the MicroMessenger(WeChat)
53
- browser.weibo? # detect Weibo embedded browser (Sina Weibo)
52
+ browser.wechat?
53
+ browser.weibo?
54
+ browser.yandex?
55
+ browser.sputnik?
54
56
 
55
57
  # Get bot info
56
58
  browser.bot.name
57
59
  browser.bot.search_engine?
58
60
  browser.bot?
61
+ Browser::Bot.why?(ua) # shows which user agent was the offender
59
62
 
60
63
  # Get device info
61
64
  browser.device
data/Rakefile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "bundler"
2
4
  require "bundler/setup"
3
5
  Bundler::GemHelper.install_tasks
@@ -28,4 +30,4 @@ task "test:all" do
28
30
  end
29
31
  end
30
32
 
31
- task default: [:test, :rubocop]
33
+ task default: %i[test rubocop]
data/bots.yml CHANGED
@@ -109,7 +109,6 @@ insieve: "Insieve Bot"
109
109
  insitesbot: "Insitesbot"
110
110
  instapaper: "Instapaper"
111
111
  istellabot: "IstellaBot"
112
- jack: "jack"
113
112
  jetslide: "Jetslide"
114
113
  jobseeker: "jobseeker.com.au/bot.html"
115
114
  jooble: "Jooble"
@@ -146,7 +145,6 @@ mfe_expand: "Mcafee spider"
146
145
  mir web crawler: "MIR web crawler"
147
146
  mj12bot: "Majestic-12 spider"
148
147
  mojeekbot: "Mojeek UK search crawler"
149
- mrchrome: "MrChrome"
150
148
  ms search 6.0 robot: "MS Search 6.0 Robot"
151
149
  msnbot-media: "Microsoft media bot"
152
150
  msnbot: "Microsoft bot"
@@ -195,6 +193,7 @@ relateiq: "RelateIQ"
195
193
  riddler: "Riddler Bot"
196
194
  rogerbot: "SeoMoz spider"
197
195
  rssmicro: "RSS/Atom Feed Robot (rssmicro.com)"
196
+ scouturlmonitor: "ScoutURLMonitor"
198
197
  scrapy: "Scrapy"
199
198
  screaming frog seo spider: Screaming Frog SEO Spider
200
199
  searchmetricsbot: "SearchmetricsBot"
@@ -212,7 +211,9 @@ sistrix: "SISTRIX"
212
211
  sitecheck: "SiteCheck sitecrawl"
213
212
  siteuptime: "Site monitoring services"
214
213
  slack: "Slackbot-LinkExpanding"
215
- slackbot: "Slack Bot"
214
+ slackbot: "Slackbot 1.0(+https://api.slack.com/robots)"
215
+ slack-imgproxy: "Slack-ImgProxy 0.19 (+https://api.slack.com/robots)"
216
+ slack-linkexpanding: "Slackbot-LinkExpanding 1.0 (+https://api.slack.com/robots)"
216
217
  slurp: "Yahoo spider"
217
218
  smtbot: "SimilarTech"
218
219
  snapchat: "Snapchat"
@@ -261,11 +262,11 @@ wesee: "WeSEE"
261
262
  wget: "wget unix CLI http client"
262
263
  whatsapp: "WhatsApp"
263
264
  wikido: "WikiDo"
265
+ woorank: "WooRank"
264
266
  wordpress: "WordPress spider"
265
267
  woriobot: "woriobot"
266
268
  wormly: "WormlyBot"
267
269
  wotbox: "Wotbox"
268
- woorank: "WooRank"
269
270
  xenu link sleuth: "Xenu Link Sleuth"
270
271
  xing-contenttabreceiver: "Xing bot"
271
272
  xovibot: "XoviBot"
@@ -1,4 +1,6 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source "https://rubygems.org"
2
4
  gemspec path: ".."
3
5
 
4
- gem "rails", '~> 5.0'
6
+ gem "rails", "~> 5.0"
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+ gemspec path: ".."
5
+
6
+ gem "rails", "~> 6.0"
@@ -52,7 +52,7 @@ module Browser
52
52
 
53
53
  # Return true if browser is modern (Webkit, Firefox 17+, IE9+, Opera 12+).
54
54
  def modern?
55
- Browser.modern_rules.any? {|rule| rule === self } # rubocop:disable Metrics/LineLength, Style/CaseEquality
55
+ Browser.modern_rules.any? {|rule| rule === self } # rubocop:disable Style/CaseEquality
56
56
  end
57
57
 
58
58
  # Detect if browser is Microsoft Internet Explorer.
@@ -84,6 +84,12 @@ module Browser
84
84
  detect_version?(full_version, expected_version)
85
85
  end
86
86
 
87
+ # Detect if browser is Snapchat.
88
+ def snapchat?(expected_version = nil)
89
+ Snapchat.new(ua).match? &&
90
+ detect_version?(full_version, expected_version)
91
+ end
92
+
87
93
  # Detect if browser if Facebook.
88
94
  def facebook?(expected_version = nil)
89
95
  Facebook.new(ua).match? &&
@@ -99,7 +105,7 @@ module Browser
99
105
  # Detect if browser is WebKit-based.
100
106
  def webkit?(expected_version = nil)
101
107
  ua =~ /AppleWebKit/i &&
102
- !edge? &&
108
+ (!edge? || Edge.new(ua).chrome_based?) &&
103
109
  detect_version?(webkit_full_version, expected_version)
104
110
  end
105
111
 
@@ -143,10 +149,16 @@ module Browser
143
149
  Opera.new(ua).match? && detect_version?(full_version, expected_version)
144
150
  end
145
151
 
152
+ # Detect if browser is Sputnik.
153
+ def sputnik?(expected_version = nil)
154
+ Sputnik.new(ua) && detect_version?(full_version, expected_version)
155
+ end
156
+
146
157
  # Detect if browser is Yandex.
147
158
  def yandex?(expected_version = nil)
148
- ua =~ /YaBrowser/ && detect_version?(full_version, expected_version)
159
+ Yandex.new(ua) && detect_version?(full_version, expected_version)
149
160
  end
161
+ alias_method :yandex_browser?, :yandex?
150
162
 
151
163
  # Detect if browser is UCBrowser.
152
164
  def uc_browser?(expected_version = nil)
@@ -24,6 +24,11 @@ module Browser
24
24
  .load_file(Browser.root.join("search_engines.yml"))
25
25
  end
26
26
 
27
+ def self.why?(ua)
28
+ downcased_ua = ua.downcase
29
+ bots.find {|key, _| downcased_ua.include?(key) }
30
+ end
31
+
27
32
  attr_reader :ua
28
33
 
29
34
  def initialize(ua)
@@ -27,6 +27,9 @@ require "browser/electron"
27
27
  require "browser/facebook"
28
28
  require "browser/otter"
29
29
  require "browser/instagram"
30
+ require "browser/yandex"
31
+ require "browser/sputnik"
32
+ require "browser/snapchat"
30
33
 
31
34
  require "browser/bot"
32
35
  require "browser/middleware"
@@ -57,10 +60,13 @@ module Browser
57
60
  Otter,
58
61
  Facebook, # must be placed before Chrome and Safari
59
62
  Instagram, # must be placed before Chrome and Safari
63
+ Snapchat, # must be placed before Chrome and Safari
60
64
  Weibo, # must be placed before Chrome and Safari
61
65
  QQ, # must be placed before Chrome and Safari
62
66
  Alipay, # must be placed before Chrome and Safari
63
67
  Electron, # must be placed before Chrome and Safari
68
+ Yandex, # must be placed before Chrome and Safari
69
+ Sputnik, # must be placed before Chrome and Safari
64
70
  Chrome,
65
71
  Safari,
66
72
  MicroMessenger,
@@ -20,7 +20,10 @@ module Browser
20
20
  end
21
21
 
22
22
  def match?
23
- ua =~ /Chrome|CriOS/ && !opera? && !edge?
23
+ ua =~ /Chrome|CriOS/ &&
24
+ ua !~ /PhantomJS|FxiOS|YaBrowser|SputnikBrowser/ &&
25
+ !opera? &&
26
+ !edge?
24
27
  end
25
28
  end
26
29
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "browser/device/base"
4
+ require "browser/device/android"
4
5
  require "browser/device/unknown"
5
6
  require "browser/device/ipad"
6
7
  require "browser/device/ipod_touch"
@@ -45,6 +46,7 @@ module Browser
45
46
  Ipad,
46
47
  Iphone,
47
48
  IpodTouch,
49
+ Android,
48
50
  Unknown
49
51
  ]
50
52
  end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Browser
4
+ class Device
5
+ class Android < Base
6
+ def id
7
+ :unknown
8
+ end
9
+
10
+ def name
11
+ ua[/\(Linux.*?; Android.*?; ([-_a-z0-9 ]+) Build[^)]+\)/i, 1] ||
12
+ "Unknown"
13
+ end
14
+
15
+ def match?
16
+ ua =~ /Android/
17
+ end
18
+ end
19
+ end
20
+ end
@@ -12,7 +12,7 @@ module Browser
12
12
  end
13
13
 
14
14
  def match?
15
- ua =~ /(tv|Android.*?ADT-1|Nexus Player)/i
15
+ ua =~ /(\btv|Android.*?ADT-1|Nexus Player)/i
16
16
  end
17
17
  end
18
18
  end
@@ -11,11 +11,15 @@ module Browser
11
11
  end
12
12
 
13
13
  def full_version
14
- ua[%r[Edge/([\d.]+)], 1] || super
14
+ ua[%r[(?:Edge|Edg)/([\d.]+)], 1] || super
15
15
  end
16
16
 
17
17
  def match?
18
- ua =~ %r[(Edge/[\d.]+|Trident/8)]
18
+ ua =~ %r[((?:Edge|Edg)/[\d.]+|Trident/8)]
19
+ end
20
+
21
+ def chrome_based?
22
+ match? && ua =~ /\bEdg\b/
19
23
  end
20
24
  end
21
25
  end
@@ -11,7 +11,7 @@ module Browser
11
11
  end
12
12
 
13
13
  def full_version
14
- ua[%r[Instagram ([\d.]+)], 1]
14
+ ua[%r[Instagram[ /]([\d.]+)], 1]
15
15
  end
16
16
 
17
17
  def match?
@@ -4,10 +4,22 @@ module Browser
4
4
  class Platform
5
5
  class IOS < Base
6
6
  MATCHER = /(iPhone|iPad|iPod)/.freeze
7
- VERSION_MATCHER = /OS ([\d.]+)/.freeze
7
+ VERSION_MATCHER = /OS ((?<major>\d)_(?<minor>\d)_?(?<patch>\d)?)/.freeze
8
8
 
9
9
  def version
10
- ua[VERSION_MATCHER, 1] || "0"
10
+ matches = VERSION_MATCHER.match(ua)
11
+
12
+ return "0" unless matches
13
+
14
+ versions = [matches[:major]]
15
+
16
+ if matches[:patch]
17
+ versions.push(matches[:minor], matches[:patch])
18
+ else
19
+ versions.push(matches[:minor]) unless matches[:minor] == "0"
20
+ end
21
+
22
+ versions.join(".")
11
23
  end
12
24
 
13
25
  def name
@@ -10,14 +10,13 @@ module Browser
10
10
 
11
11
  initializer "browser" do
12
12
  ActiveSupport.on_load(:action_controller) do
13
- ::ActionController::Base.send :include, Browser::ActionController
13
+ ::ActionController::Base.include(Browser::ActionController)
14
14
 
15
15
  if defined?(::ActionController::Metal)
16
- ::ActionController::Metal.send :include, Browser::ActionController
16
+ ::ActionController::Metal.include(Browser::ActionController)
17
17
  end
18
18
 
19
- Browser::Middleware::Context.send(
20
- :include,
19
+ Browser::Middleware::Context.include(
21
20
  Browser::Middleware::Context::Additions
22
21
  )
23
22
  end
@@ -18,7 +18,7 @@ module Browser
18
18
  end
19
19
 
20
20
  def match?
21
- ua =~ /Safari/ && ua !~ /Chrome|CriOS|PhantomJS|FxiOS/
21
+ ua =~ /Safari/ && ua !~ /Chrome|CriOS|PhantomJS|FxiOS|YaBrowser/
22
22
  end
23
23
  end
24
24
  end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Browser
4
+ class Snapchat < Base
5
+ def id
6
+ :snapchat
7
+ end
8
+
9
+ def name
10
+ "Snapchat"
11
+ end
12
+
13
+ def full_version
14
+ ua[%r[Snapchat/([\d.]+)], 1]
15
+ end
16
+
17
+ def match?
18
+ ua =~ /Snapchat/
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Browser
4
+ class Sputnik < Base
5
+ def id
6
+ :sputnik
7
+ end
8
+
9
+ def name
10
+ "Sputnik"
11
+ end
12
+
13
+ def full_version
14
+ # Each regex on its own line to enforce precedence.
15
+ ua[%r[SputnikBrowser/([\d.]+)], 1] ||
16
+ ua[%r[Chrome/([\d.]+)], 1] ||
17
+ "0.0"
18
+ end
19
+
20
+ def match?
21
+ ua =~ /SputnikBrowser/
22
+ end
23
+ end
24
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Browser
4
- VERSION = "2.6.1"
4
+ VERSION = "2.7.0"
5
5
  end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Browser
4
+ class Yandex < Base
5
+ def id
6
+ :yandex
7
+ end
8
+
9
+ def name
10
+ "Yandex"
11
+ end
12
+
13
+ def full_version
14
+ ua[%r[YaBrowser/([\d.]+)], 1] || "0.0"
15
+ end
16
+
17
+ def match?
18
+ ua =~ /YaBrowser/
19
+ end
20
+ end
21
+ end
@@ -24,6 +24,11 @@ class SampleApp < Rails::Application
24
24
  config.eager_load = true
25
25
  config.active_support.deprecation = :log
26
26
 
27
+ # Introduced by Rails 6.
28
+ if config.respond_to?(:hosts)
29
+ config.hosts << "example.org"
30
+ end
31
+
27
32
  routes.append do
28
33
  default_headers = {"Content-Type" => "text/html"}
29
34
 
@@ -1,3 +1,4 @@
1
+ ---
1
2
  ADOBE_AIR: "Mozilla/5.0 (Macintosh; U; Intel Mac OS X; de) AppleWebKit/533.19.4 (KHTML, like Gecko) AdobeAIR/13.0"
2
3
  ALIPAY_ANDROID: "Mozilla/5.0 (Linux; U; Android 4.2.1; zh-cn; HUAWEI G610-T00 Build/HuaweiG610-T00) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30 AlipayDefined(nt:WIFI,ws:360|640|1.5) AliApp(AP/9.0.1.073001) AlipayClient/9.0.1.073001 GCanvas/1.4.2.15"
3
4
  ALIPAY_IOS: "Mozilla/5.0 (iPhone; CPU iPhone OS 7_0 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A465 Safari/9537.53 AliApp(AP/2.3.4) AlipayClient/2.3.4"
@@ -55,12 +56,15 @@ IE9_CHROME_FRAME: "Mozilla/5.0 (Windows NT 6.1; WOW64; chromeframe/26.0.1410.43)
55
56
  IE9_COMPAT: "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; Trident/5.0)"
56
57
  IE_WITHOUT_TRIDENT: Mozilla/4.0 (compatible; MSIE8.0; Windows NT 6.0) .NET CLR 2.0.50727)
57
58
  INSTAGRAM: "Mozilla/5.0 (iPhone; CPU iPhone OS 11_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E216 Instagram 41.0.0.14.90 (iPhone9,3; iOS 11_3; pl_PL; pl-PL; scale=2.00; gamut=wide; 750x1334)"
59
+ INSTAGRAM_OTHER: "Instagram/182257141 CFNetwork/1107.1 Darwin/19.0.0"
58
60
  IOS3: "Mozilla/5.0 (iPad; U; CPU iPhone OS 3_0 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B314 Safari/531.21.10"
59
61
  IOS4: "Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_0 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8A293 Safari/6531.22.7"
60
62
  IOS5: "Mozilla/5.0 (iPhone; CPU iPhone OS 5_0 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9A334 Safari/7534.48.3"
61
63
  IOS6: "Mozilla/5.0 (iPhone; CPU iPhone OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5376e Safari/8536.25"
62
64
  IOS7: "Mozilla/5.0 (iPhone; CPU iPhone OS 7_0 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A465 Safari/9537.53"
63
65
  IOS8: "Mozilla/5.0 (iPhone; CPU iPhone OS 8_0 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile/12A365 Safari/600.1.4"
66
+ IOS8_1_2: 'Mozilla/5.0 (iPhone; CPU iPhone OS 8_1_2 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile/12B440 Safari/600.1.4'
67
+ IOS8_3: 'Mozilla/5.0 (iPhone; CPU iPhone OS 8_3 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile/12F70 Safari/600.1.4'
64
68
  IOS9: "Mozilla/5.0 (iPad; CPU OS 9_0 like Mac OS X) AppleWebKit/601.1.17 (KHTML, like Gecko) Version/8.0 Mobile/13A175 Safari/600.1.4"
65
69
  IOS_WEBVIEW: Mozilla/5.0 (iPhone; CPU iPhone OS 8_4 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Mobile/12H141
66
70
  IPAD: "Mozilla/5.0 (iPad; U; CPU OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B367 Safari/531.21.10"
@@ -75,6 +79,7 @@ MICRO_MESSENGER: "Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_1 like Mac OS X) AppleW
75
79
  MIDP: MIDP-2.0
76
80
  MOBILE_CHROME: "Mozilla/5.0 (iPhone; U; CPU iPhone OS 5_1_1 like Mac OS X; en) AppleWebKit/534.46.0 (KHTML, like Gecko) CriOS/19.0.1084.60 Mobile/9B206 Safari/7534.48.3"
77
81
  MS_EDGE: "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36 Edge/12.0"
82
+ MS_EDGE_CHROME: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.29 Safari/537.36 Edg/79.0.309.18"
78
83
  MS_EDGE_COMPAT: "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.2; WOW64; Trident/8.0; .NET4.0C; .NET4.0E; Tablet PC 2.0; Microsoft Outlook 15.0.4433; ms-office; MSOffice 15)"
79
84
  MS_EDGE_MOBILE: "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; DEVICE INFO) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Mobile Safari/537.36 Edge/12.0"
80
85
  NEXUS7: "Mozilla/5.0 (Linux; Android 4.3; Nexus 7 Build/JWR66Y) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.72 Safari/537.36"
@@ -114,6 +119,8 @@ SAFARI_IPHONE_WEBAPP_MODE: "Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_2 like Mac O
114
119
  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"
115
120
  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"
116
121
  SMART_TV: "Mozilla/5.0 (SmartHub; SMART-TV; U; Linux/SmartTV) AppleWebKit/531.2+ (KHTML, like Gecko) WebBrowser/1.0 SmartTV Safari/531.2+"
122
+ 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)
123
+ 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"
117
124
  SURFACE: "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; ARM; Trident/6.0; Touch)"
118
125
  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"
119
126
  TABLOID: "Mozilla/5.0 (Linux; U; Android 3.0; en-us; Xoom Build/HRI39) AppleWebKit/534.13 (KHTML, like Gecko) Version/4.0 Safari/534.13"
@@ -137,4 +144,5 @@ WINDOWS_XP_64: "Mozilla/4.0 (Compatible; MSIE 8.0; Windows NT 5.2; Trident/6.0)"
137
144
  XBOX360: "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0; Xbox), or Mozilla/5.0 (compatible; MSIE 9.0; Windows Phone OS 7.5; Trident/5.0; IEMobile/9.0; Xbox)"
138
145
  XBOXONE: "Mozilla/5.0 (Compatible; MSIE 10.0; Windows NT 6.2; Trident /6.0; Xbox; Xbox One)"
139
146
  XOOM: "Mozilla/5.0 (Linux; U; Android 3.0; en-us; Xoom Build/HRI39) AppleWebKit/534.13 (KHTML, like Gecko) Version/4.0 Safari/534.13"
140
- YANDEX_BROWSER: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.118 YaBrowser/15.4.2272.3909 (beta) Yowser/2.0 Safari/537.36"
147
+ YANDEX_BROWSER_DESKTOP: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 YaBrowser/19.6.0.1583 Yowser/2.5 Safari/537.36"
148
+ YANDEX_BROWSER_IOS: "Mozilla/5.0 (iPhone; CPU iPhone OS 12_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 YaBrowser/19.6.1.157.10 Mobile/15E148 Safari/605.1"
@@ -1,3 +1,4 @@
1
+ ---
1
2
  ADLXBOT: "Mozilla/5.0 (compatible; adidxbot/2.0; +http://www.bing.com/bingbot.htm)"
2
3
  ADS_TXT_CRAWLER: "AdsTxtCrawler/1.0"
3
4
  ANDERSPINK: "Mozilla/5.0 (compatible; AndersPinkBot/1.0; +http://anderspink.com/bot.html)"
@@ -49,7 +50,6 @@ MAPPYDATA: "Mozilla/5.0 (compatible; Mappy/1.0; +http://mappydata.net/bot/)"
49
50
  MASTODONBOT: "http.rb/3.0.0 (Mastodon/2.2.0; +https://mstdn.io/)"
50
51
  MAUIBOT: "MauiBot (crawler.feedback+wc@gmail.com)"
51
52
  MEGAINDEX_RU: "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
52
- MRCHROME: "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.107 Amigo/45.0.2454.107 MRCHROME SOC Safari/537.36"
53
53
  MSNBOT: "msnbot/2.0b (+http://search.msn.com/msnbot.htm)"
54
54
  MSNBOT_MEDIA: "msnbot-media/1.1 (+http://search.msn.com/msnbot.htm)"
55
55
  NETCRAFT2: Netcraft SSL Server Survey - contact info@netcraft.com
@@ -62,6 +62,7 @@ PROXIMIC: "Mozilla/5.0 (compatible; proximic; +http://www.proximic.com/info/spid
62
62
  PUINCRAWLER: "Pu_iN Crawler (+http://semanticjuice.com/)"
63
63
  QUERYSEEKER: "QuerySeekerSpider ( http://queryseeker.com/bot.html )"
64
64
  QUICKCRAWLER: "Quick-Crawler (+https://www.scrapinghub.com/)"
65
+ SCOUT_URL_MONITOR: ScoutURLMonitor/6.2.2
65
66
  SCRAPY: "Scrapy/0.18.4 (+http://scrapy.org)"
66
67
  SEMANTICBOT: "Mozilla/5.0 (compatible; Semanticbot/1.0; +http://sempi.tech/bot.html)"
67
68
  SEO_AUDIT: "Mozilla/5.0 (compatible; seo-audit-check-bot/1.0)"
@@ -69,7 +70,6 @@ SEODIVER: "Mozilla/5.0 (compatible; SEOdiver/1.0; +http://www.seodiver.com/bot)"
69
70
  SEOKICKS: "Mozilla/5.0 (compatible; SEOkicks-Robot; +http://www.seokicks.de/robot.html)"
70
71
  SISTRIX: "Mozilla/5.0 (compatible; SISTRIX Crawler; http://crawler.sistrix.net/)"
71
72
  SITECHECK: 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.0) SiteCheck-sitecrawl by Siteimprove.com'
72
- SNAPCHAT: "Mozilla/5.0 (iPhone; CPU iPhone OS 11_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Snapchat/10.37.1.1 (iPhone9,4; iOS 11.4; gzip)"
73
73
  SOCIALRANKIO: SocialRankIOBot; http://socialrank.io/about
74
74
  SQUIDER: "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.110 Safari/537.36 Squider/0.01"
75
75
  STRIPE: "Stripe/1.0 (+https://stripe.com/docs/webhooks)"
@@ -114,4 +114,11 @@ class BotsTest < Minitest::Test
114
114
  assert browser.bot?
115
115
  assert_equal "LinkedIn", browser.bot.name
116
116
  end
117
+
118
+ test "tells why user agent is considered a bot" do
119
+ id, name = Browser::Bot.why?(Browser.bot_user_agents["LINKEDIN"])
120
+
121
+ assert_equal "linkedinbot", id
122
+ assert_equal "LinkedIn", name
123
+ end
117
124
  end
@@ -45,22 +45,6 @@ class ChromeTest < Minitest::Test
45
45
  assert browser.platform.chrome_os?
46
46
  end
47
47
 
48
- test "detects yandex browser" do
49
- browser = Browser.new(Browser["YANDEX_BROWSER"])
50
-
51
- assert browser.yandex?
52
- assert browser.chrome?
53
- refute browser.safari?
54
- assert browser.webkit?
55
- assert_equal "41.0.2272.118", browser.full_version
56
- assert_equal "41", browser.version
57
- end
58
-
59
- test "detects yandex version by range" do
60
- browser = Browser.new(Browser["YANDEX_BROWSER"])
61
- assert browser.yandex?(%w[>=41 <42])
62
- end
63
-
64
48
  test "detects chrome frame" do
65
49
  browser = Browser.new(Browser["IE9_CHROME_FRAME"])
66
50
 
@@ -238,4 +238,24 @@ class DeviceTest < Minitest::Test
238
238
  refute device.mobile?
239
239
  end
240
240
  end
241
+
242
+ {
243
+ "ANDROID_CUPCAKE" => "T-Mobile G1",
244
+ "ANDROID_DONUT" => "SonyEricssonX10i",
245
+ "ANDROID_ECLAIR_21" => "Nexus One",
246
+ "ANDROID_FROYO" => "HTC_DesireHD_A9191",
247
+ "ANDROID_GINGERBREAD" => "Sensation_4G",
248
+ "ANDROID_HONEYCOMB_30" => "Xoom",
249
+ "ANDROID_ICECREAM" => "sdk",
250
+ "ANDROID_JELLYBEAN_41" => "Nexus S",
251
+ "ANDROID_JELLYBEAN_42" => "Nexus 10",
252
+ "ANDROID_JELLYBEAN_43" => "Nexus 7",
253
+ "CUSTOM_APP" => "HTC Ruby",
254
+ "NOOK" => "NOOK BNTV250A"
255
+ }.each do |key, name|
256
+ test "detect device name of #{key} as #{name}" do
257
+ device = Browser::Device.new(Browser[key])
258
+ assert_equal name, device.name
259
+ end
260
+ end
241
261
  end
@@ -53,6 +53,22 @@ class EdgeTest < ActionController::TestCase
53
53
  refute browser.safari?
54
54
  end
55
55
 
56
+ test "detects Microsoft Edge based on Chrome" do
57
+ browser = Browser.new(Browser["MS_EDGE_CHROME"])
58
+
59
+ assert_equal :edge, browser.id
60
+ assert_equal "Microsoft Edge", browser.name
61
+ assert_equal "79.0.309.18", browser.full_version
62
+ assert_equal "79", browser.version
63
+ assert browser.platform.mac?
64
+ refute browser.platform.windows?
65
+ assert browser.edge?
66
+ assert browser.modern?
67
+ assert browser.webkit?
68
+ refute browser.chrome?
69
+ refute browser.safari?
70
+ end
71
+
56
72
  test "detects version by range" do
57
73
  browser = Browser.new(Browser["MS_EDGE"])
58
74
  assert browser.edge?(%w[>=12 <13])
@@ -13,6 +13,16 @@ class InstagramTest < Minitest::Test
13
13
  assert_equal "41", browser.version
14
14
  end
15
15
 
16
+ test "detects alternate instagram user agent" do
17
+ browser = Browser.new(Browser["INSTAGRAM_OTHER"])
18
+
19
+ assert_equal "Instagram", browser.name
20
+ assert browser.instagram?
21
+ assert :instagram, browser.id
22
+ assert_equal "182257141", browser.full_version
23
+ assert_equal "182257141", browser.version
24
+ end
25
+
16
26
  test "detects version by range" do
17
27
  browser = Browser.new(Browser["INSTAGRAM"])
18
28
  assert browser.instagram?(%w[>=41])
@@ -62,6 +62,27 @@ class PlatformTest < Minitest::Test
62
62
  assert_equal "9", platform.version
63
63
  end
64
64
 
65
+ test "detect specific minor iOS (iPhone)" do
66
+ platform = Browser::Platform.new(Browser["IOS8_3"])
67
+
68
+ assert_equal "iOS (iPhone)", platform.name
69
+ assert_equal :ios, platform.id
70
+ assert platform.ios?
71
+ assert platform.ios?(8.3)
72
+ assert_equal "8.3", platform.version
73
+ end
74
+
75
+ test "detect specific patch iOS (iPhone)" do
76
+ platform = Browser::Platform.new(Browser["IOS8_1_2"])
77
+
78
+ assert_equal "iOS (iPhone)", platform.name
79
+ assert_equal :ios, platform.id
80
+ assert platform.ios?
81
+ assert platform.ios?("8.1.2")
82
+ assert platform.ios?("<8.2")
83
+ assert_equal "8.1.2", platform.version
84
+ end
85
+
65
86
  test "detect ios (iPod Touch)" do
66
87
  platform = Browser::Platform.new(Browser["IPOD"])
67
88
 
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
4
+
5
+ class SnapchatTest < Minitest::Test
6
+ test "detects snapchat" do
7
+ browser = Browser.new(Browser["SNAPCHAT"])
8
+
9
+ assert_equal "Snapchat", browser.name
10
+ assert browser.snapchat?
11
+ assert :snapchat, browser.id
12
+ assert_equal "10.69.5.72", browser.full_version
13
+ assert_equal "10", browser.version
14
+ end
15
+
16
+ test "detects version by range" do
17
+ browser = Browser.new(Browser["SNAPCHAT"])
18
+ assert browser.snapchat?(%w[>=10])
19
+ end
20
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
4
+
5
+ class SputnikTest < Minitest::Test
6
+ test "detects sputnik" do
7
+ browser = Browser.new(Browser["SPUTNIK"])
8
+
9
+ assert_equal "Sputnik", browser.name
10
+ assert browser.sputnik?
11
+ refute browser.chrome?
12
+ refute browser.safari?
13
+ assert_equal "4.1.2801.0", browser.full_version
14
+ assert_equal "4", browser.version
15
+ end
16
+
17
+ test "detects version by range" do
18
+ browser = Browser.new(Browser["SPUTNIK"])
19
+ assert browser.sputnik?(%w[>=4 <5])
20
+ end
21
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
4
+
5
+ class YandexTest < Minitest::Test
6
+ test "detects Yandex on iOS device" do
7
+ browser = Browser.new(Browser["YANDEX_BROWSER_IOS"])
8
+ assert browser.yandex?
9
+ assert browser.yandex_browser?
10
+ refute browser.safari?
11
+ refute browser.chrome?
12
+ assert browser.webkit?
13
+ assert_equal "Yandex", browser.name
14
+ assert_equal :yandex, browser.id
15
+ end
16
+
17
+ test "detects Yandex on non-iOS devices" do
18
+ browser = Browser.new(Browser["YANDEX_BROWSER_DESKTOP"])
19
+ assert browser.yandex?
20
+ assert browser.yandex_browser?
21
+ refute browser.safari?
22
+ refute browser.chrome?
23
+ assert_equal "Yandex", browser.name
24
+ assert_equal :yandex, browser.id
25
+ end
26
+
27
+ test "detects correct version" do
28
+ browser = Browser.new(Browser["YANDEX_BROWSER_DESKTOP"])
29
+ assert_equal "19.6.0.1583", browser.full_version
30
+ assert_equal "19", browser.version
31
+ end
32
+
33
+ test "detects version by range" do
34
+ browser = Browser.new(Browser["YANDEX_BROWSER_DESKTOP"])
35
+ assert browser.yandex?(%w[>=18 <20])
36
+ end
37
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: browser
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.6.1
4
+ version: 2.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nando Vieira
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-07-16 00:00:00.000000000 Z
11
+ date: 2019-11-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -171,6 +171,7 @@ files:
171
171
  - browser.gemspec
172
172
  - config.ru
173
173
  - gemfiles/rails5.gemfile
174
+ - gemfiles/rails6.gemfile
174
175
  - languages.yml
175
176
  - lib/browser.rb
176
177
  - lib/browser/accept_language.rb
@@ -184,6 +185,7 @@ files:
184
185
  - lib/browser/chrome.rb
185
186
  - lib/browser/detect_version.rb
186
187
  - lib/browser/device.rb
188
+ - lib/browser/device/android.rb
187
189
  - lib/browser/device/base.rb
188
190
  - lib/browser/device/blackberry_playbook.rb
189
191
  - lib/browser/device/ipad.rb
@@ -250,10 +252,13 @@ files:
250
252
  - lib/browser/qq.rb
251
253
  - lib/browser/rails.rb
252
254
  - lib/browser/safari.rb
255
+ - lib/browser/snapchat.rb
256
+ - lib/browser/sputnik.rb
253
257
  - lib/browser/testing.rb
254
258
  - lib/browser/uc_browser.rb
255
259
  - lib/browser/version.rb
256
260
  - lib/browser/weibo.rb
261
+ - lib/browser/yandex.rb
257
262
  - search_engines.yml
258
263
  - test/browser_test.rb
259
264
  - test/middleware_test.rb
@@ -293,10 +298,13 @@ files:
293
298
  - test/unit/proxy_test.rb
294
299
  - test/unit/qq_test.rb
295
300
  - test/unit/safari_test.rb
301
+ - test/unit/snapchat_test.rb
302
+ - test/unit/sputnik_test.rb
296
303
  - test/unit/uc_browser_test.rb
297
304
  - test/unit/weibo_test.rb
298
305
  - test/unit/windows_phone_test.rb
299
306
  - test/unit/windows_test.rb
307
+ - test/unit/yandex_test.rb
300
308
  homepage: http://github.com/fnando/browser
301
309
  licenses:
302
310
  - MIT
@@ -359,7 +367,10 @@ test_files:
359
367
  - test/unit/proxy_test.rb
360
368
  - test/unit/qq_test.rb
361
369
  - test/unit/safari_test.rb
370
+ - test/unit/snapchat_test.rb
371
+ - test/unit/sputnik_test.rb
362
372
  - test/unit/uc_browser_test.rb
363
373
  - test/unit/weibo_test.rb
364
374
  - test/unit/windows_phone_test.rb
365
375
  - test/unit/windows_test.rb
376
+ - test/unit/yandex_test.rb