browsed 0.2.3 → 0.2.4

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: 61e83765b6257c39cd97be1c3764a20bb20e90b6ce602c94d693b0fb4444bf64
4
- data.tar.gz: 8f747af9a52257cd1a05aecfddbd81fc714e76253472eba5ef7724a6dce1e10f
3
+ metadata.gz: f711eb863313bb4ebb804b8a8d531304b76d9faea6afb4ad347fb418acd267b3
4
+ data.tar.gz: f5f7016f636a77f68519aa7db4847a3989b3f44e9b9c59326e3acbd0976b06e9
5
5
  SHA512:
6
- metadata.gz: 666a4dd2ace58b39da9b7132493c0f64dc605fb50de3db3363b21f18caaa643be3cc33321c6ce5e94c372735e998e8ba611262a683591351f3512617f125ddee
7
- data.tar.gz: 4b191391235827932b9b8e16942802757424bfb77f25b0a9076243ba8fa520f9da87a3faf293c29e321be0c8e64503d375fd5901344c480e5e744b8739837399
6
+ metadata.gz: eb714bc6d80b581185835d26d96d7ae3b1de0b673d0b9ef071f26a74dd4a15066bfaf6e7269b33e005ad4fe0197b90a8345b4466cc03d3dd807d648ed4c14df8
7
+ data.tar.gz: b4744b3813485365e683a4fa0a1d131ee0fb2032319b2e01dc466d413060bac1623ef0189c90db80855fe63cfd6146e8c133d2b6dda3bf8ff30bb8eede33a736
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- browsed (0.2.1)
4
+ browsed (0.2.4)
5
5
  agents (>= 0.1.4)
6
6
  capybara (>= 2.18)
7
7
  poltergeist (>= 1.18)
@@ -13,26 +13,25 @@ GEM
13
13
  addressable (2.6.0)
14
14
  public_suffix (>= 2.0.2, < 4.0)
15
15
  agents (0.1.4)
16
- capybara (3.15.0)
16
+ capybara (3.25.0)
17
17
  addressable
18
18
  mini_mime (>= 0.1.3)
19
19
  nokogiri (~> 1.8)
20
20
  rack (>= 1.6.0)
21
21
  rack-test (>= 0.6.3)
22
- regexp_parser (~> 1.2)
22
+ regexp_parser (~> 1.5)
23
23
  xpath (~> 3.2)
24
- childprocess (0.9.0)
25
- ffi (~> 1.0, >= 1.0.11)
24
+ childprocess (1.0.1)
25
+ rake (< 13.0)
26
26
  cliver (0.3.2)
27
27
  coderay (1.1.2)
28
28
  diff-lcs (1.3)
29
- ffi (1.10.0)
30
29
  launchy (2.4.3)
31
30
  addressable (~> 2.3)
32
31
  method_source (0.9.2)
33
32
  mini_mime (1.0.1)
34
33
  mini_portile2 (2.4.0)
35
- nokogiri (1.10.2)
34
+ nokogiri (1.10.3)
36
35
  mini_portile2 (~> 2.4.0)
37
36
  poltergeist (1.18.1)
38
37
  capybara (>= 2.1, < 4)
@@ -41,32 +40,32 @@ GEM
41
40
  pry (0.12.2)
42
41
  coderay (~> 1.1.0)
43
42
  method_source (~> 0.9.0)
44
- public_suffix (3.0.3)
45
- rack (2.0.6)
43
+ public_suffix (3.1.1)
44
+ rack (2.0.7)
46
45
  rack-test (1.1.0)
47
46
  rack (>= 1.0, < 3)
48
47
  rake (12.3.2)
49
- regexp_parser (1.3.0)
48
+ regexp_parser (1.5.1)
50
49
  rspec (3.8.0)
51
50
  rspec-core (~> 3.8.0)
52
51
  rspec-expectations (~> 3.8.0)
53
52
  rspec-mocks (~> 3.8.0)
54
- rspec-core (3.8.0)
53
+ rspec-core (3.8.2)
55
54
  rspec-support (~> 3.8.0)
56
- rspec-expectations (3.8.2)
55
+ rspec-expectations (3.8.4)
57
56
  diff-lcs (>= 1.2.0, < 2.0)
58
57
  rspec-support (~> 3.8.0)
59
- rspec-mocks (3.8.0)
58
+ rspec-mocks (3.8.1)
60
59
  diff-lcs (>= 1.2.0, < 2.0)
61
60
  rspec-support (~> 3.8.0)
62
- rspec-support (3.8.0)
63
- rubyzip (1.2.2)
64
- selenium-webdriver (3.141.0)
65
- childprocess (~> 0.5)
61
+ rspec-support (3.8.2)
62
+ rubyzip (1.2.3)
63
+ selenium-webdriver (3.142.3)
64
+ childprocess (>= 0.5, < 2.0)
66
65
  rubyzip (~> 1.2, >= 1.2.2)
67
- websocket-driver (0.7.0)
66
+ websocket-driver (0.7.1)
68
67
  websocket-extensions (>= 0.1.0)
69
- websocket-extensions (0.1.3)
68
+ websocket-extensions (0.1.4)
70
69
  xpath (3.2.0)
71
70
  nokogiri (~> 1.8)
72
71
 
@@ -75,11 +74,11 @@ PLATFORMS
75
74
 
76
75
  DEPENDENCIES
77
76
  browsed!
78
- bundler (~> 2.0.1)
77
+ bundler (~> 1.17)
79
78
  launchy (~> 2.4, >= 2.4.3)
80
79
  pry (~> 0.12.2)
81
80
  rake (~> 12.3.2)
82
81
  rspec (~> 3.8.0)
83
82
 
84
83
  BUNDLED WITH
85
- 2.0.1
84
+ 1.17.2
data/README.md CHANGED
@@ -40,6 +40,12 @@ Use the session property to interact with the underlying Capybara::Session objec
40
40
  client.session.visit("https://www.google.com")
41
41
  ```
42
42
 
43
+ ## Support
44
+
45
+ Proxy authentication is currently only supported by PhantomJS and Chrome not running in headless mode.
46
+
47
+ Chrome proxy authentication support is somewhat of a hack and works by dynamically generating a plugin on the fly and then starting Chrome with that plugin. Unfortunately this doesn't work in headless Chrome.
48
+
43
49
  ## Development
44
50
 
45
51
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -29,7 +29,7 @@ Gem::Specification.new do |spec|
29
29
 
30
30
  spec.add_dependency "agents", '>= 0.1.4'
31
31
 
32
- spec.add_development_dependency "bundler", "~> 2.0.1"
32
+ spec.add_development_dependency "bundler", "~> 1.17"
33
33
  spec.add_development_dependency "rake", "~> 12.3.2"
34
34
  spec.add_development_dependency "rspec", "~> 3.8.0"
35
35
  spec.add_development_dependency "pry", "~> 0.12.2"
@@ -14,6 +14,8 @@ require "browsed/configuration"
14
14
 
15
15
  require "browsed/manager"
16
16
 
17
+ require "browsed/extensions/chrome/proxy_authentication"
18
+
17
19
  require "browsed/poltergeist"
18
20
  require "browsed/firefox"
19
21
  require "browsed/chrome"
@@ -9,11 +9,15 @@ module Browsed
9
9
 
10
10
  profile["user-agent"] = self.user_agent unless self.user_agent.to_s.empty?
11
11
 
12
- proxy_options = chrome_proxy_options
13
- capabilities = !proxy_options.nil? ? Selenium::WebDriver::Remote::Capabilities.chrome(proxy: proxy_options) : {}
12
+ proxy_options = manage_chrome_proxy
13
+ proxy_capabilities = proxy_options[:capabilities]
14
+ capabilities = !proxy_capabilities.nil? ? Selenium::WebDriver::Remote::Capabilities.chrome(proxy: proxy_capabilities) : {}
15
+ proxy_plugin_path = proxy_options[:plugin_path]
16
+
14
17
  args = %w(disable-popup-blocking)
15
18
  args = args | %W(window-size=#{resolution.first},#{resolution.last}) if resolution && resolution.any? && resolution.size.eql?(2)
16
19
  args = args | %w(headless disable-gpu) if headless
20
+ args = args | %W(load-extension=#{proxy_plugin_path}) unless proxy_plugin_path.to_s.empty?
17
21
 
18
22
  options = Selenium::WebDriver::Chrome::Options.new(profile: profile, args: args)
19
23
 
@@ -22,8 +26,9 @@ module Browsed
22
26
  end
23
27
  end
24
28
 
25
- def chrome_proxy_options
29
+ def manage_chrome_proxy
26
30
  proxy_options = nil
31
+ plugin_path = nil
27
32
 
28
33
  if self.proxy && !self.proxy.empty? && self.proxy.has_key?(:host) && self.proxy.has_key?(:port)
29
34
  proxy_options = Selenium::WebDriver::Proxy.new(
@@ -32,9 +37,15 @@ module Browsed
32
37
  )
33
38
 
34
39
  log("Will use proxy #{self.proxy.fetch(:host)}:#{self.proxy.fetch(:port)} to initiate the request.")
40
+
41
+ if !headless? && !self.proxy[:username].to_s.empty? && !self.proxy[:password].to_s.empty?
42
+ log("Generating a new proxy plugin to manage proxy authentication.")
43
+
44
+ plugin_path = Browser::Extensions::Chrome::ProxyAuthentication::Packager.package_extension(proxy, self.configuration.temp_path)
45
+ end
35
46
  end
36
47
 
37
- return proxy_options
48
+ return {capabilities: proxy_options, plugin_path: plugin_path}
38
49
  end
39
50
 
40
51
  end
@@ -3,7 +3,7 @@ module Browsed
3
3
  attr_accessor :configuration
4
4
  attr_accessor :driver, :browser, :browser_id, :environment
5
5
  attr_accessor :session, :proxy
6
- attr_accessor :device, :user_agent, :resolution
6
+ attr_accessor :device, :user_agent, :resolution, :headless
7
7
  attr_accessor :manager, :maximum_processes
8
8
 
9
9
  include Capybara::DSL
@@ -25,6 +25,7 @@ module Browsed
25
25
  self.browser = browser || self.configuration.browser
26
26
  self.environment = environment || self.configuration.environment
27
27
 
28
+ self.headless = false
28
29
  self.browser_id = generate_browser_id
29
30
  self.device = device
30
31
  self.proxy = proxy
@@ -112,11 +113,13 @@ module Browsed
112
113
  elsif firefox_browser?
113
114
  register_firefox_driver(options: options)
114
115
  elsif firefox_headless_browser?
116
+ self.headless = true
115
117
  register_firefox_driver(options: options.merge(headless: true))
116
118
  elsif chrome_browser?
117
119
  self.driver = :selenium_chrome
118
120
  register_chrome_driver(options: options.merge(resolution: self.resolution))
119
121
  elsif chrome_headless_browser?
122
+ self.headless = true
120
123
  self.driver = :selenium_chrome_headless
121
124
  register_chrome_driver(options: options.merge(resolution: self.resolution, headless: true))
122
125
  end
@@ -153,6 +156,10 @@ module Browsed
153
156
  def in_environment?(env)
154
157
  self.environment.eql?(env)
155
158
  end
159
+
160
+ def headless?
161
+ self.headless
162
+ end
156
163
 
157
164
  # User Agents
158
165
  def set_user_agent(user_agent)
@@ -1,7 +1,7 @@
1
1
  module Browsed
2
2
  class Configuration
3
3
  attr_accessor :driver, :browser, :environment
4
- attr_accessor :binary_path, :download_path
4
+ attr_accessor :binary_path, :root_path, :download_path, :temp_path
5
5
  attr_accessor :maximum_processes, :processes_max_ttl
6
6
  attr_accessor :verbose
7
7
 
@@ -13,7 +13,9 @@ module Browsed
13
13
 
14
14
  self.binary_path = "/usr/local/bin/phantomjs"
15
15
 
16
+ self.root_path = File.expand_path(File.join(__FILE__, "../../.."))
16
17
  self.download_path = nil
18
+ self.temp_path = "/tmp"
17
19
 
18
20
  self.maximum_processes = nil
19
21
  self.processes_max_ttl = 60 * 30 # 30 minutes
@@ -0,0 +1,78 @@
1
+ module Browser
2
+ module Extensions
3
+ module Chrome
4
+ module ProxyAuthentication
5
+
6
+ class Packager
7
+ def self.package_extension(proxy, path)
8
+ file_id = Digest::SHA1.hexdigest("#{proxy[:username]}:#{proxy[:password]}@#{proxy[:host]}:#{proxy[:port]}")
9
+ plugin_path = "#{path}/chrome-proxy-authentication-plugin-#{file_id}"
10
+ FileUtils.mkdir_p plugin_path
11
+
12
+ manifest_file = "#{plugin_path}/manifest.json"
13
+ File.open(manifest_file, 'w') { |file| file.write(::Browser::Extensions::Chrome::ProxyAuthentication::MANIFEST_JSON_TEMPLATE) }
14
+
15
+ script_file = "#{plugin_path}/background.js"
16
+ script_result = Browser::Extensions::Chrome::ProxyAuthentication::BACKGROUND_SCRIPT_TEMPLATE % [proxy[:host], proxy[:port], proxy[:username], proxy[:password]]
17
+ File.open(script_file, 'w') { |file| file.write(script_result) }
18
+
19
+ return plugin_path
20
+ end
21
+ end
22
+
23
+ MANIFEST_JSON_TEMPLATE = <<-TEMPLATE
24
+ {
25
+ "version": "1.0.0",
26
+ "manifest_version": 2,
27
+ "name": "Chrome Proxy",
28
+ "permissions": [
29
+ "proxy",
30
+ "tabs",
31
+ "unlimitedStorage",
32
+ "storage",
33
+ "<all_urls>",
34
+ "webRequest",
35
+ "webRequestBlocking"
36
+ ],
37
+ "background": {
38
+ "scripts": ["background.js"]
39
+ },
40
+ "minimum_chrome_version":"22.0.0"
41
+ }
42
+ TEMPLATE
43
+
44
+ BACKGROUND_SCRIPT_TEMPLATE = <<-TEMPLATE
45
+ var config = {
46
+ mode: "fixed_servers",
47
+ rules: {
48
+ singleProxy: {
49
+ scheme: "http",
50
+ host: "%s",
51
+ port: parseInt(%s)
52
+ },
53
+ bypassList: ["localhost"]
54
+ }
55
+ };
56
+
57
+ chrome.proxy.settings.set({value: config, scope: "regular"}, function() {});
58
+
59
+ function callbackFn(details) {
60
+ return {
61
+ authCredentials: {
62
+ username: "%s",
63
+ password: "%s"
64
+ }
65
+ };
66
+ }
67
+
68
+ chrome.webRequest.onAuthRequired.addListener(
69
+ callbackFn,
70
+ {urls: ["<all_urls>"]},
71
+ ['blocking']
72
+ );
73
+ TEMPLATE
74
+
75
+ end
76
+ end
77
+ end
78
+ end
@@ -42,10 +42,16 @@ module Browsed
42
42
 
43
43
  def firefox_proxy_options(profile)
44
44
  if self.proxy && !self.proxy.empty? && self.proxy.has_key?(:host) && self.proxy.has_key?(:port)
45
- profile.proxy = Selenium::WebDriver::Proxy.new(
46
- http: "#{self.proxy.fetch(:host)}:#{self.proxy.fetch(:port)}",
47
- ssl: "#{self.proxy.fetch(:host)}:#{self.proxy.fetch(:port)}"
45
+ proxy_config = Selenium::WebDriver::Proxy.new(
46
+ http: "#{self.proxy.fetch(:host)}:#{self.proxy.fetch(:port)}",
47
+ ssl: "#{self.proxy.fetch(:host)}:#{self.proxy.fetch(:port)}",
48
+ socks: "#{self.proxy.fetch(:host)}:#{self.proxy.fetch(:port)}"
48
49
  )
50
+
51
+ proxy_config.socks_username = self.proxy.fetch(:username) unless self.proxy.fetch(:username, nil).to_s.empty?
52
+ proxy_config.socks_password = self.proxy.fetch(:password) unless self.proxy.fetch(:password, nil).to_s.empty?
53
+
54
+ profile.proxy = proxy_config
49
55
 
50
56
  log("Will use proxy #{self.proxy.fetch(:host)}:#{self.proxy.fetch(:port)} to initiate the request.")
51
57
  end
@@ -1,3 +1,3 @@
1
1
  module Browsed
2
- VERSION = "0.2.3"
2
+ VERSION = "0.2.4"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: browsed
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sebastian
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-03-27 00:00:00.000000000 Z
11
+ date: 2019-07-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: capybara
@@ -72,14 +72,14 @@ dependencies:
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: 2.0.1
75
+ version: '1.17'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: 2.0.1
82
+ version: '1.17'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: rake
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -168,6 +168,7 @@ files:
168
168
  - lib/browsed/configuration.rb
169
169
  - lib/browsed/constants.rb
170
170
  - lib/browsed/errors.rb
171
+ - lib/browsed/extensions/chrome/proxy_authentication.rb
171
172
  - lib/browsed/firefox.rb
172
173
  - lib/browsed/manager.rb
173
174
  - lib/browsed/poltergeist.rb