browser 2.6.1 → 2.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 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