browsed 0.2.5 → 0.2.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (172) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/Gemfile.lock +2 -2
  4. data/README.md +12 -17
  5. data/bin/browse +13 -10
  6. data/lib/browsed.rb +9 -2
  7. data/lib/browsed/browser.rb +82 -0
  8. data/lib/browsed/chrome.rb +21 -12
  9. data/lib/browsed/client.rb +48 -130
  10. data/lib/browsed/constants.rb +7 -1
  11. data/lib/browsed/errors.rb +1 -0
  12. data/lib/browsed/extensions/hash.rb +27 -0
  13. data/lib/browsed/firefox.rb +18 -17
  14. data/lib/browsed/manager.rb +5 -5
  15. data/lib/browsed/{poltergeist.rb → phantomjs.rb} +2 -2
  16. data/lib/browsed/proxies.rb +26 -0
  17. data/lib/browsed/{extensions → proxies}/chrome/proxy_authentication.rb +3 -3
  18. data/lib/browsed/proxies/proxy-chain-server/node_modules/.bin/portastic +1 -0
  19. data/lib/browsed/proxies/proxy-chain-server/node_modules/bluebird/LICENSE +21 -0
  20. data/lib/browsed/proxies/proxy-chain-server/node_modules/bluebird/README.md +57 -0
  21. data/lib/browsed/proxies/proxy-chain-server/node_modules/bluebird/changelog.md +1 -0
  22. data/lib/browsed/proxies/proxy-chain-server/node_modules/bluebird/js/browser/bluebird.core.js +3824 -0
  23. data/lib/browsed/proxies/proxy-chain-server/node_modules/bluebird/js/browser/bluebird.core.min.js +31 -0
  24. data/lib/browsed/proxies/proxy-chain-server/node_modules/bluebird/js/browser/bluebird.js +5666 -0
  25. data/lib/browsed/proxies/proxy-chain-server/node_modules/bluebird/js/browser/bluebird.min.js +31 -0
  26. data/lib/browsed/proxies/proxy-chain-server/node_modules/bluebird/js/release/any.js +21 -0
  27. data/lib/browsed/proxies/proxy-chain-server/node_modules/bluebird/js/release/assert.js +55 -0
  28. data/lib/browsed/proxies/proxy-chain-server/node_modules/bluebird/js/release/async.js +165 -0
  29. data/lib/browsed/proxies/proxy-chain-server/node_modules/bluebird/js/release/bind.js +67 -0
  30. data/lib/browsed/proxies/proxy-chain-server/node_modules/bluebird/js/release/bluebird.js +11 -0
  31. data/lib/browsed/proxies/proxy-chain-server/node_modules/bluebird/js/release/call_get.js +123 -0
  32. data/lib/browsed/proxies/proxy-chain-server/node_modules/bluebird/js/release/cancel.js +129 -0
  33. data/lib/browsed/proxies/proxy-chain-server/node_modules/bluebird/js/release/catch_filter.js +42 -0
  34. data/lib/browsed/proxies/proxy-chain-server/node_modules/bluebird/js/release/context.js +69 -0
  35. data/lib/browsed/proxies/proxy-chain-server/node_modules/bluebird/js/release/debuggability.js +934 -0
  36. data/lib/browsed/proxies/proxy-chain-server/node_modules/bluebird/js/release/direct_resolve.js +46 -0
  37. data/lib/browsed/proxies/proxy-chain-server/node_modules/bluebird/js/release/each.js +30 -0
  38. data/lib/browsed/proxies/proxy-chain-server/node_modules/bluebird/js/release/errors.js +116 -0
  39. data/lib/browsed/proxies/proxy-chain-server/node_modules/bluebird/js/release/es5.js +80 -0
  40. data/lib/browsed/proxies/proxy-chain-server/node_modules/bluebird/js/release/filter.js +12 -0
  41. data/lib/browsed/proxies/proxy-chain-server/node_modules/bluebird/js/release/finally.js +146 -0
  42. data/lib/browsed/proxies/proxy-chain-server/node_modules/bluebird/js/release/generators.js +223 -0
  43. data/lib/browsed/proxies/proxy-chain-server/node_modules/bluebird/js/release/join.js +168 -0
  44. data/lib/browsed/proxies/proxy-chain-server/node_modules/bluebird/js/release/map.js +168 -0
  45. data/lib/browsed/proxies/proxy-chain-server/node_modules/bluebird/js/release/method.js +55 -0
  46. data/lib/browsed/proxies/proxy-chain-server/node_modules/bluebird/js/release/nodeback.js +51 -0
  47. data/lib/browsed/proxies/proxy-chain-server/node_modules/bluebird/js/release/nodeify.js +58 -0
  48. data/lib/browsed/proxies/proxy-chain-server/node_modules/bluebird/js/release/promise.js +789 -0
  49. data/lib/browsed/proxies/proxy-chain-server/node_modules/bluebird/js/release/promise_array.js +185 -0
  50. data/lib/browsed/proxies/proxy-chain-server/node_modules/bluebird/js/release/promisify.js +314 -0
  51. data/lib/browsed/proxies/proxy-chain-server/node_modules/bluebird/js/release/props.js +118 -0
  52. data/lib/browsed/proxies/proxy-chain-server/node_modules/bluebird/js/release/queue.js +73 -0
  53. data/lib/browsed/proxies/proxy-chain-server/node_modules/bluebird/js/release/race.js +49 -0
  54. data/lib/browsed/proxies/proxy-chain-server/node_modules/bluebird/js/release/reduce.js +172 -0
  55. data/lib/browsed/proxies/proxy-chain-server/node_modules/bluebird/js/release/schedule.js +62 -0
  56. data/lib/browsed/proxies/proxy-chain-server/node_modules/bluebird/js/release/settle.js +43 -0
  57. data/lib/browsed/proxies/proxy-chain-server/node_modules/bluebird/js/release/some.js +148 -0
  58. data/lib/browsed/proxies/proxy-chain-server/node_modules/bluebird/js/release/synchronous_inspection.js +103 -0
  59. data/lib/browsed/proxies/proxy-chain-server/node_modules/bluebird/js/release/thenables.js +86 -0
  60. data/lib/browsed/proxies/proxy-chain-server/node_modules/bluebird/js/release/timers.js +93 -0
  61. data/lib/browsed/proxies/proxy-chain-server/node_modules/bluebird/js/release/using.js +226 -0
  62. data/lib/browsed/proxies/proxy-chain-server/node_modules/bluebird/js/release/util.js +389 -0
  63. data/lib/browsed/proxies/proxy-chain-server/node_modules/bluebird/package.json +102 -0
  64. data/lib/browsed/proxies/proxy-chain-server/node_modules/commander/CHANGELOG.md +408 -0
  65. data/lib/browsed/proxies/proxy-chain-server/node_modules/commander/LICENSE +22 -0
  66. data/lib/browsed/proxies/proxy-chain-server/node_modules/commander/Readme.md +428 -0
  67. data/lib/browsed/proxies/proxy-chain-server/node_modules/commander/index.js +1224 -0
  68. data/lib/browsed/proxies/proxy-chain-server/node_modules/commander/package.json +70 -0
  69. data/lib/browsed/proxies/proxy-chain-server/node_modules/commander/typings/index.d.ts +310 -0
  70. data/lib/browsed/proxies/proxy-chain-server/node_modules/debug/.coveralls.yml +1 -0
  71. data/lib/browsed/proxies/proxy-chain-server/node_modules/debug/.eslintrc +11 -0
  72. data/lib/browsed/proxies/proxy-chain-server/node_modules/debug/.npmignore +9 -0
  73. data/lib/browsed/proxies/proxy-chain-server/node_modules/debug/.travis.yml +14 -0
  74. data/lib/browsed/proxies/proxy-chain-server/node_modules/debug/CHANGELOG.md +362 -0
  75. data/lib/browsed/proxies/proxy-chain-server/node_modules/debug/LICENSE +19 -0
  76. data/lib/browsed/proxies/proxy-chain-server/node_modules/debug/Makefile +50 -0
  77. data/lib/browsed/proxies/proxy-chain-server/node_modules/debug/README.md +312 -0
  78. data/lib/browsed/proxies/proxy-chain-server/node_modules/debug/component.json +19 -0
  79. data/lib/browsed/proxies/proxy-chain-server/node_modules/debug/karma.conf.js +70 -0
  80. data/lib/browsed/proxies/proxy-chain-server/node_modules/debug/node.js +1 -0
  81. data/lib/browsed/proxies/proxy-chain-server/node_modules/debug/package.json +88 -0
  82. data/lib/browsed/proxies/proxy-chain-server/node_modules/debug/src/browser.js +185 -0
  83. data/lib/browsed/proxies/proxy-chain-server/node_modules/debug/src/debug.js +202 -0
  84. data/lib/browsed/proxies/proxy-chain-server/node_modules/debug/src/index.js +10 -0
  85. data/lib/browsed/proxies/proxy-chain-server/node_modules/debug/src/inspector-log.js +15 -0
  86. data/lib/browsed/proxies/proxy-chain-server/node_modules/debug/src/node.js +248 -0
  87. data/lib/browsed/proxies/proxy-chain-server/node_modules/ms/index.js +152 -0
  88. data/lib/browsed/proxies/proxy-chain-server/node_modules/ms/license.md +21 -0
  89. data/lib/browsed/proxies/proxy-chain-server/node_modules/ms/package.json +69 -0
  90. data/lib/browsed/proxies/proxy-chain-server/node_modules/ms/readme.md +51 -0
  91. data/lib/browsed/proxies/proxy-chain-server/node_modules/portastic/LICENSE +13 -0
  92. data/lib/browsed/proxies/proxy-chain-server/node_modules/portastic/README.md +148 -0
  93. data/lib/browsed/proxies/proxy-chain-server/node_modules/portastic/bin/portastic +65 -0
  94. data/lib/browsed/proxies/proxy-chain-server/node_modules/portastic/history.md +7 -0
  95. data/lib/browsed/proxies/proxy-chain-server/node_modules/portastic/index.js +4 -0
  96. data/lib/browsed/proxies/proxy-chain-server/node_modules/portastic/lib/monitor.js +59 -0
  97. data/lib/browsed/proxies/proxy-chain-server/node_modules/portastic/lib/portastic.js +167 -0
  98. data/lib/browsed/proxies/proxy-chain-server/node_modules/portastic/node_modules/bluebird/LICENSE +21 -0
  99. data/lib/browsed/proxies/proxy-chain-server/node_modules/portastic/node_modules/bluebird/README.md +677 -0
  100. data/lib/browsed/proxies/proxy-chain-server/node_modules/portastic/node_modules/bluebird/changelog.md +1730 -0
  101. data/lib/browsed/proxies/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/browser/bluebird.js +4892 -0
  102. data/lib/browsed/proxies/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/browser/bluebird.min.js +31 -0
  103. data/lib/browsed/proxies/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/any.js +21 -0
  104. data/lib/browsed/proxies/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/assert.js +55 -0
  105. data/lib/browsed/proxies/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/async.js +150 -0
  106. data/lib/browsed/proxies/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/bind.js +72 -0
  107. data/lib/browsed/proxies/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/bluebird.js +11 -0
  108. data/lib/browsed/proxies/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/call_get.js +123 -0
  109. data/lib/browsed/proxies/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/cancel.js +48 -0
  110. data/lib/browsed/proxies/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/captured_trace.js +493 -0
  111. data/lib/browsed/proxies/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/catch_filter.js +66 -0
  112. data/lib/browsed/proxies/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/context.js +38 -0
  113. data/lib/browsed/proxies/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/debuggability.js +162 -0
  114. data/lib/browsed/proxies/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/direct_resolve.js +63 -0
  115. data/lib/browsed/proxies/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/each.js +12 -0
  116. data/lib/browsed/proxies/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/errors.js +111 -0
  117. data/lib/browsed/proxies/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/es5.js +80 -0
  118. data/lib/browsed/proxies/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/filter.js +12 -0
  119. data/lib/browsed/proxies/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/finally.js +98 -0
  120. data/lib/browsed/proxies/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/generators.js +136 -0
  121. data/lib/browsed/proxies/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/join.js +107 -0
  122. data/lib/browsed/proxies/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/map.js +133 -0
  123. data/lib/browsed/proxies/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/method.js +44 -0
  124. data/lib/browsed/proxies/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/nodeify.js +59 -0
  125. data/lib/browsed/proxies/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/progress.js +76 -0
  126. data/lib/browsed/proxies/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/promise.js +759 -0
  127. data/lib/browsed/proxies/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/promise_array.js +142 -0
  128. data/lib/browsed/proxies/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/promise_resolver.js +123 -0
  129. data/lib/browsed/proxies/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/promisify.js +307 -0
  130. data/lib/browsed/proxies/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/props.js +79 -0
  131. data/lib/browsed/proxies/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/queue.js +90 -0
  132. data/lib/browsed/proxies/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/race.js +47 -0
  133. data/lib/browsed/proxies/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/reduce.js +148 -0
  134. data/lib/browsed/proxies/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/schedule.js +35 -0
  135. data/lib/browsed/proxies/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/settle.js +40 -0
  136. data/lib/browsed/proxies/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/some.js +125 -0
  137. data/lib/browsed/proxies/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/synchronous_inspection.js +94 -0
  138. data/lib/browsed/proxies/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/thenables.js +84 -0
  139. data/lib/browsed/proxies/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/timers.js +64 -0
  140. data/lib/browsed/proxies/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/using.js +213 -0
  141. data/lib/browsed/proxies/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/util.js +321 -0
  142. data/lib/browsed/proxies/proxy-chain-server/node_modules/portastic/node_modules/bluebird/package.json +103 -0
  143. data/lib/browsed/proxies/proxy-chain-server/node_modules/portastic/package.json +69 -0
  144. data/lib/browsed/proxies/proxy-chain-server/node_modules/proxy-chain/CHANGELOG.md +109 -0
  145. data/lib/browsed/proxies/proxy-chain-server/node_modules/proxy-chain/LICENSE +201 -0
  146. data/lib/browsed/proxies/proxy-chain-server/node_modules/proxy-chain/README.md +278 -0
  147. data/lib/browsed/proxies/proxy-chain-server/node_modules/proxy-chain/build/anonymize_proxy.js +100 -0
  148. data/lib/browsed/proxies/proxy-chain-server/node_modules/proxy-chain/build/handler_base.js +319 -0
  149. data/lib/browsed/proxies/proxy-chain-server/node_modules/proxy-chain/build/handler_custom_response.js +96 -0
  150. data/lib/browsed/proxies/proxy-chain-server/node_modules/proxy-chain/build/handler_forward.js +173 -0
  151. data/lib/browsed/proxies/proxy-chain-server/node_modules/proxy-chain/build/handler_tunnel_chain.js +132 -0
  152. data/lib/browsed/proxies/proxy-chain-server/node_modules/proxy-chain/build/handler_tunnel_direct.js +89 -0
  153. data/lib/browsed/proxies/proxy-chain-server/node_modules/proxy-chain/build/handler_tunnel_tcp_chain.js +271 -0
  154. data/lib/browsed/proxies/proxy-chain-server/node_modules/proxy-chain/build/index.js +26 -0
  155. data/lib/browsed/proxies/proxy-chain-server/node_modules/proxy-chain/build/run_locally.js +66 -0
  156. data/lib/browsed/proxies/proxy-chain-server/node_modules/proxy-chain/build/server.js +595 -0
  157. data/lib/browsed/proxies/proxy-chain-server/node_modules/proxy-chain/build/tcp_tunnel.js +138 -0
  158. data/lib/browsed/proxies/proxy-chain-server/node_modules/proxy-chain/build/testing_tcp_service.js +37 -0
  159. data/lib/browsed/proxies/proxy-chain-server/node_modules/proxy-chain/build/tools.js +220 -0
  160. data/lib/browsed/proxies/proxy-chain-server/node_modules/proxy-chain/package.json +104 -0
  161. data/lib/browsed/proxies/proxy-chain-server/node_modules/underscore/LICENSE +23 -0
  162. data/lib/browsed/proxies/proxy-chain-server/node_modules/underscore/README.md +28 -0
  163. data/lib/browsed/proxies/proxy-chain-server/node_modules/underscore/package.json +81 -0
  164. data/lib/browsed/proxies/proxy-chain-server/node_modules/underscore/underscore-min.js +5 -0
  165. data/lib/browsed/proxies/proxy-chain-server/node_modules/underscore/underscore-min.js.map +1 -0
  166. data/lib/browsed/proxies/proxy-chain-server/node_modules/underscore/underscore.js +1692 -0
  167. data/lib/browsed/proxies/proxy-chain-server/package-lock.json +63 -0
  168. data/lib/browsed/proxies/proxy-chain-server/package.json +15 -0
  169. data/lib/browsed/proxies/proxy-chain-server/server.js +25 -0
  170. data/lib/browsed/proxies/proxy_chain.rb +36 -0
  171. data/lib/browsed/version.rb +1 -1
  172. metadata +160 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 343ac6bd7d2660fa5503615f384933df9dae903a69d242791edf03ba75d93fea
4
- data.tar.gz: aa8d6d88db9dd61ae94fb4bc60f1b30c60923239209e1732cc7613c14e97accd
3
+ metadata.gz: 4ce77ce8ab4a14169daeb61e3af46f43340b248d84c81cdda763777e7c152bea
4
+ data.tar.gz: 2694ba144b2f55c5a7e1dd8231c258092828794b3d5f229edf126814aa2c176f
5
5
  SHA512:
6
- metadata.gz: 20439f0110dac3a95d059f47feedc6d2a26d15b7bf3830f5d633307100aa0e6d0e0ade531dd46692dcfd02ffdd69d8f8e241818310a1bbf1f6fee520ee5143e6
7
- data.tar.gz: 3002d0d9c1c76be747c03d5e6f162fd97e7c51e1b8f1bc0ad97c5224a812cd51a821a4ac314f8b7be5219c8dcce0948b44b46b6cd5ad0e6f3881399e8e295b6b
6
+ metadata.gz: 80c7d784ad587b6202e2c4cec78830793e7f1101f10a8c6c49c2bce6c47e556b4019ac6fc616ebda318fce632834f5fd7fd10d85080c2fb3cfa9ce9091d933df
7
+ data.tar.gz: 4ec3b57515d439944e62ea0c791e92c4c97c64600b7b47342bc81dd7e9b02fd1c63aac0a5989931950c9862e15621c936d49e21ae98b2d8d5f6d5c0db401176e
data/.gitignore CHANGED
@@ -9,6 +9,8 @@
9
9
  /tmp/
10
10
  /files/
11
11
 
12
+ proxies.yml
13
+
12
14
  # rspec failure tracking
13
15
  .rspec_status
14
16
 
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- browsed (0.2.4)
4
+ browsed (0.2.5)
5
5
  agents (>= 0.1.4)
6
6
  capybara (>= 2.18)
7
7
  poltergeist (>= 1.18)
@@ -29,7 +29,7 @@ GEM
29
29
  launchy (2.4.3)
30
30
  addressable (~> 2.3)
31
31
  method_source (0.9.2)
32
- mini_mime (1.0.1)
32
+ mini_mime (1.0.2)
33
33
  mini_portile2 (2.4.0)
34
34
  nokogiri (1.10.3)
35
35
  mini_portile2 (~> 2.4.0)
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Browsed
2
2
 
3
- Browsed is a lightweight Capybara/PhantomJS/Selenium framework with tools and utilities for randomizing user agents, resolutions etc.
3
+ Browsed is a wrapper around Capybara/Selenium with tools for proxy management and utilities for randomizing user agents, resolutions etc.
4
4
 
5
5
  ## Installation
6
6
 
@@ -21,31 +21,26 @@ Or install it yourself as:
21
21
  ## Usage
22
22
 
23
23
  ```ruby
24
- # driver can be :poltergeist (PhantomJS) or :selenium/:selenium_chrome/:selenium_chrome_headless (Firefox/Chrome)
25
- # browser can be: :phantomjs, :chrome, :chrome_headless, :firefox, :firefox_headless
24
+ # browser can be: :chrome, :firefox or :phantomjs (PhantomJS might be deprecated eventually though)
26
25
  # device can be :desktop, :phone (iphone/android), :tablet (ipad/android), :iphone, :ipad, :android_phone, :android_tablet
27
- client = Browsed::Client.new(driver: :selenium_chrome, browser: :chrome, device: :desktop)
26
+ client = Browsed::Client.new(browser: :chrome, headless: false, device: :desktop)
27
+ client.session.visit "https://www.google.com"
28
28
  ```
29
29
 
30
- If you want to use proxies (note that proxy authentication is only possible using Poltergeist/PhantomJS):
30
+ Proxy auth support is supported using two different methods:
31
31
 
32
- ```ruby
33
- proxy = {host: "127.0.0.1", port: 8080, username: "foo", password: "bar"}
34
- client = Browsed::Client.new(driver: :poltergeist, browser: :phantomjs, device: :desktop, proxy: proxy)
35
- ```
32
+ 1) For non-headless Google Chrome a plugin will be generated on the fly and used by Chrome to auto-fill username/password for the proxy. Major downside with this approach is that Chrome can't be run in headless mode.
33
+
34
+ 2) Using the NodeJS library proxy-chain. Browsed will spawn a Node sub-process that will run a local proxy server that forwards all packets to the final proxy server. When the client is finished (by issuing client.quit!) the proxy-chain server will also be terminated. Major downside: depends on Node being installed.
36
35
 
37
- Use the session property to interact with the underlying Capybara::Session object:
36
+ Here's an example using a proxy via proxy-chain:
38
37
 
39
38
  ```ruby
40
- client.session.visit("https://www.google.com")
39
+ proxy = {host: "127.0.0.1", port: 8080, username: "foo", password: "bar", mode: :proxy_chain}
40
+ client = Browsed::Client.new(browser: :chrome, headless: false, device: :desktop, proxy: proxy)
41
+ client.session.visit "https://www.google.com"
41
42
  ```
42
43
 
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
-
49
44
  ## Development
50
45
 
51
46
  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.
data/bin/browse CHANGED
@@ -3,24 +3,27 @@
3
3
  require "bundler/setup"
4
4
  require "browsed"
5
5
  require "launchy"
6
+ require "yaml"
6
7
 
7
- driver = :selenium_chrome
8
- browser = :chrome
8
+ url = "https://whatismyipaddress.com"
9
+ screenshot = File.expand_path("../../files/#{Time.now.to_i}.png", __FILE__)
9
10
 
10
- url = "https://whatismyipaddress.com"
11
- path = File.expand_path("../../files/#{Time.now.to_i}.png", __FILE__)
11
+ path = File.join(File.dirname(__FILE__), "../proxies.yml")
12
+ proxy = ::File.exists?(path) ? YAML.load_file(path).symbolize_keys : nil
12
13
 
13
- client = Browsed::Client.new(
14
- driver: driver,
15
- browser: browser,
14
+ client = Browsed::Client.new(
15
+ browser: :chrome,
16
+ headless: true,
16
17
  device: :desktop,
17
18
  environment: :development,
18
19
  user_agent: :randomize,
19
20
  resolution: [1920,1080],
20
- options: {open_timeout: 30, read_timeout: 30}
21
+ options: {open_timeout: 30, read_timeout: 30},
22
+ proxy: proxy
21
23
  )
22
24
 
23
25
  client.resize! # Set resolution
24
26
  client.session.visit(url)
25
- client.session.save_screenshot(path)
26
- client.display_screenshot!(path)
27
+ client.session.save_screenshot(screenshot)
28
+ client.display_screenshot!(screenshot)
29
+ client.quit!
@@ -14,13 +14,20 @@ require "browsed/configuration"
14
14
 
15
15
  require "browsed/manager"
16
16
 
17
- require "browsed/extensions/chrome/proxy_authentication"
17
+ require "browsed/proxies/chrome/proxy_authentication"
18
+ require "browsed/proxies/proxy_chain"
18
19
 
19
- require "browsed/poltergeist"
20
+ require "browsed/proxies"
21
+ require "browsed/browser"
22
+ require "browsed/phantomjs"
20
23
  require "browsed/firefox"
21
24
  require "browsed/chrome"
22
25
  require "browsed/client"
23
26
 
27
+ if !Hash.instance_methods(false).include?(:symbolize_keys)
28
+ require "browsed/extensions/hash"
29
+ end
30
+
24
31
  module Browsed
25
32
 
26
33
  class << self
@@ -0,0 +1,82 @@
1
+ module Browsed
2
+ module Browser
3
+
4
+ def generate_browser_id
5
+ SecureRandom.hex
6
+ end
7
+
8
+ # Resize the window separately and not based on initialization
9
+ def resize!(res = nil)
10
+ res ||= self.resolution
11
+
12
+ if res && res.size.eql?(2) && resizable_browser? # Resolutions for Chrome & Poltergeist are set in the driver
13
+ self.session.current_window.resize_to(res.first, res.last) # [width, height]
14
+ end
15
+ end
16
+
17
+ def resizable_browser?
18
+ non_resizable = [:poltergeist, :selenium_chrome, :selenium_chrome_headless]
19
+ !non_resizable.include?(self.driver.to_sym)
20
+ end
21
+
22
+ # User Agents
23
+ def set_user_agent(user_agent)
24
+ if !user_agent.to_s.empty? && !user_agent.to_sym.eql?(:randomize)
25
+ self.user_agent = user_agent
26
+ elsif (!user_agent.to_s.empty? && user_agent.to_sym.eql?(:randomize)) || phantomjs?
27
+ case self.device
28
+ when :iphone
29
+ self.user_agent = Agents.random_user_agent(:phones, :iphone)
30
+ when :android_phone
31
+ self.user_agent = Agents.random_user_agent(:phones, :android)
32
+ when :ipad
33
+ self.user_agent = Agents.random_user_agent(:tablets, :ipad)
34
+ when :android_tablet
35
+ self.user_agent = Agents.random_user_agent(:tablets, :android)
36
+ else
37
+ self.user_agent = Agents.random_user_agent(self.device)
38
+ end
39
+ end
40
+ end
41
+
42
+ def runs_ios?
43
+ Agents.runs_ios?(self.user_agent)
44
+ end
45
+
46
+ def is_iphone?
47
+ Agents.is_iphone?(self.user_agent)
48
+ end
49
+
50
+ def is_ipad?
51
+ Agents.is_ipad?(self.user_agent)
52
+ end
53
+
54
+ # Resolution
55
+ def set_resolution(res)
56
+ if res && res.is_a?(Array)
57
+ self.resolution = res
58
+ elsif res && res.is_a?(Symbol) && res.eql?(:randomize)
59
+ self.resolution = randomize_resolution
60
+ end
61
+ end
62
+
63
+ def randomize_resolution
64
+ runs_ios? ? randomize_ios_resolution : Browsed::Constants::RESOLUTIONS.fetch(self.device, :desktop).sample
65
+ end
66
+
67
+ def randomize_ios_resolution
68
+ resolution_device = case self.device
69
+ when :iphone, :android_phone
70
+ :phone
71
+ when :ipad, :android_tablet
72
+ :tablet
73
+ else
74
+ self.device
75
+ end
76
+
77
+ random_key = Browsed::Constants::RESOLUTIONS.fetch(resolution_device, :desktop).keys.sample
78
+ resolution = Browsed::Constants::RESOLUTIONS.fetch(resolution_device, :desktop)[random_key]
79
+ end
80
+
81
+ end
82
+ end
@@ -29,21 +29,30 @@ module Browsed
29
29
  end
30
30
 
31
31
  def manage_chrome_proxy
32
- proxy_options = nil
33
- plugin_path = nil
32
+ proxy_options = nil
33
+ plugin_path = nil
34
34
 
35
- if self.proxy && !self.proxy.empty? && self.proxy.has_key?(:host) && self.proxy.has_key?(:port)
36
- proxy_options = Selenium::WebDriver::Proxy.new(
37
- http: "#{self.proxy.fetch(:host)}:#{self.proxy.fetch(:port)}",
38
- ssl: "#{self.proxy.fetch(:host)}:#{self.proxy.fetch(:port)}"
39
- )
35
+ if valid_proxy?
36
+ if self.proxy.fetch(:mode, nil).eql?(:proxy_chain) && proxy_using_auth?
37
+ self.proxy_chain_server = Browsed::Proxies::ProxyChain.new(self.browser_id)
38
+ log("Starting a new proxy chain server instance.")
39
+
40
+ generated_proxy_url = self.proxy_chain_server.start_server(generate_proxy_auth_url)
41
+
42
+ log("Started a new proxy chain server instance at #{generated_proxy_url}.")
43
+
44
+ uri = URI.parse(generated_proxy_url)
45
+ proxy_options = generate_selenium_webdriver_proxy(host: uri.host, port: uri.port)
46
+
47
+ else
48
+ proxy_options = generate_selenium_webdriver_proxy(host: self.proxy.fetch(:host), port: self.proxy.fetch(:port))
40
49
 
41
- log("Will use proxy #{self.proxy.fetch(:host)}:#{self.proxy.fetch(:port)} to initiate the request.")
50
+ log("Will use proxy #{self.proxy.fetch(:host)}:#{self.proxy.fetch(:port)} to initiate the request.")
42
51
 
43
- if !headless? && !self.proxy[:username].to_s.empty? && !self.proxy[:password].to_s.empty?
44
- log("Generating a new proxy plugin to manage proxy authentication.")
45
-
46
- plugin_path = Browser::Extensions::Chrome::ProxyAuthentication::Packager.package_extension(proxy, self.configuration.temp_path)
52
+ if !headless? && proxy_using_auth?
53
+ log("Generating a new proxy plugin to manage proxy authentication.")
54
+ plugin_path = Browser::Proxies::Chrome::ProxyAuthentication::Packager.package_extension(proxy, self.configuration.temp_path)
55
+ end
47
56
  end
48
57
  end
49
58
 
@@ -1,8 +1,8 @@
1
1
  module Browsed
2
2
  class Client
3
3
  attr_accessor :configuration
4
- attr_accessor :driver, :browser, :browser_id, :environment
5
- attr_accessor :session, :proxy
4
+ attr_accessor :driver, :browser, :browser_id, :headless, :environment
5
+ attr_accessor :session, :proxy, :proxy_chain_server
6
6
  attr_accessor :device, :user_agent, :resolution, :headless
7
7
  attr_accessor :manager, :maximum_processes
8
8
 
@@ -11,6 +11,7 @@ module Browsed
11
11
  def initialize(configuration: ::Browsed.configuration,
12
12
  driver: :selenium_chrome,
13
13
  browser: :chrome,
14
+ headless: false,
14
15
  device: :desktop,
15
16
  proxy: nil,
16
17
  user_agent: nil,
@@ -19,20 +20,20 @@ module Browsed
19
20
  options: {},
20
21
  maximum_processes: nil)
21
22
 
22
- self.configuration = configuration
23
+ self.configuration = configuration
24
+ self.headless = headless
25
+ self.environment = environment || self.configuration.environment
23
26
 
24
- self.driver = driver || self.configuration.driver
25
- self.browser = browser || self.configuration.browser
26
- self.environment = environment || self.configuration.environment
27
+ self.device = device
27
28
 
28
- self.headless = false
29
- self.browser_id = generate_browser_id
30
- self.device = device
31
- self.proxy = proxy
29
+ self.proxy = proxy
30
+ self.proxy_chain_server = nil
32
31
 
33
- self.manager = ::Browsed::Manager.new(browser: self.browser)
34
- self.maximum_processes = maximum_processes || self.configuration.maximum_processes
32
+ self.manager = ::Browsed::Manager.new(browser: self.browser)
33
+ self.maximum_processes = maximum_processes || self.configuration.maximum_processes
35
34
 
35
+ set_browser(browser)
36
+ set_driver
36
37
  set_user_agent(user_agent)
37
38
  set_resolution(resolution)
38
39
 
@@ -40,9 +41,29 @@ module Browsed
40
41
  setup_capybara(options: options)
41
42
  end
42
43
 
43
- include ::Browsed::Poltergeist
44
+ include ::Browsed::Browser
45
+ include ::Browsed::Proxies
44
46
  include ::Browsed::Firefox
45
47
  include ::Browsed::Chrome
48
+ include ::Browsed::Phantomjs
49
+
50
+ def set_driver
51
+ self.driver = case self.browser.to_sym
52
+ when :chrome
53
+ self.headless ? :selenium_chrome_headless : :selenium_chrome
54
+ when :firefox
55
+ :selenium
56
+ when :phantomjs
57
+ :poltergeist
58
+ end
59
+ end
60
+
61
+ def set_browser(browser)
62
+ self.browser = (browser || self.configuration.browser)&.to_sym
63
+ self.browser_id = generate_browser_id
64
+
65
+ raise ::Browsed::Errors::InvalidBrowserError unless ::Browsed::Constants::BROWSERS.include?(self.browser)
66
+ end
46
67
 
47
68
  def setup_capybara(options: {}, retries: 3)
48
69
  self.manager.kill_stale_processes!
@@ -69,27 +90,9 @@ module Browsed
69
90
  Launchy.open path if development?
70
91
  end
71
92
 
72
- # Resize the window separately and not based on initialization
73
- def resize!(res = nil)
74
- res ||= self.resolution
75
-
76
- if res && res.size.eql?(2) && resizable_browser?(self.driver) # Resolutions for Chrome & Poltergeist are set in the driver
77
- self.session.current_window.resize_to(res.first, res.last) # [width, height]
78
- end
79
- end
80
-
81
- def resizable_browser?(driver)
82
- non_resizable = [:poltergeist, :selenium_chrome, :selenium_chrome_headless]
83
- !non_resizable.include?(driver.to_sym)
84
- end
85
-
86
93
  def reset_session!
87
94
  self.session.reset_session!
88
95
  end
89
-
90
- def generate_browser_id
91
- SecureRandom.hex[0..15]
92
- end
93
96
 
94
97
  def quit!(retries: 3)
95
98
  begin
@@ -103,52 +106,37 @@ module Browsed
103
106
  self.manager.set_command(browser_id: self.browser_id)
104
107
  self.manager.kill_processes!
105
108
 
106
- self.session = nil
109
+ if self.proxy_chain_server
110
+ self.proxy_chain_server.stop_server
111
+ self.proxy_chain_server = nil
112
+ end
113
+
114
+ self.session = nil
107
115
  end
108
116
 
109
117
  private
110
118
  def register_driver!(options = {})
111
- if poltergeist?
112
- register_poltergeist_driver(options: options)
113
- elsif firefox_browser?
114
- register_firefox_driver(options: options)
115
- elsif firefox_headless_browser?
116
- self.headless = true
119
+ if firefox?
117
120
  register_firefox_driver(options: options)
118
- elsif chrome_browser?
119
- self.driver = :selenium_chrome
120
- register_chrome_driver(options: options.merge(resolution: self.resolution))
121
- elsif chrome_headless_browser?
122
- self.headless = true
123
- self.driver = :selenium_chrome_headless
121
+ elsif chrome?
124
122
  register_chrome_driver(options: options.merge(resolution: self.resolution))
123
+ elsif phantomjs?
124
+ register_phantomjs_driver(options: options)
125
125
  end
126
126
  end
127
127
 
128
- def poltergeist?
129
- self.driver.to_sym.eql?(:poltergeist)
128
+ def phantomjs?
129
+ self.browser.to_sym.eql?(:phantomjs)
130
130
  end
131
131
 
132
- def selenium?
133
- self.driver.to_sym.eql?(:selenium)
134
- end
135
-
136
- def firefox_browser?
132
+ def firefox?
137
133
  self.browser.to_sym.eql?(:firefox)
138
134
  end
139
135
 
140
- def firefox_headless_browser?
141
- self.browser.to_sym.eql?(:firefox_headless)
142
- end
143
-
144
- def chrome_browser?
136
+ def chrome?
145
137
  self.browser.to_sym.eql?(:chrome)
146
138
  end
147
139
 
148
- def chrome_headless_browser?
149
- self.browser.to_sym.eql?(:chrome_headless)
150
- end
151
-
152
140
  def development?
153
141
  in_environment?(:development)
154
142
  end
@@ -160,76 +148,6 @@ module Browsed
160
148
  def headless?
161
149
  self.headless
162
150
  end
163
-
164
- # User Agents
165
- def set_user_agent(user_agent)
166
- if !user_agent.to_s.empty? && !user_agent.to_sym.eql?(:randomize)
167
- self.user_agent = user_agent
168
- elsif (!user_agent.to_s.empty? && user_agent.to_sym.eql?(:randomize)) || poltergeist?
169
- case self.device
170
- when :iphone
171
- self.user_agent = Agents.random_user_agent(:phones, :iphone)
172
- when :android_phone
173
- self.user_agent = Agents.random_user_agent(:phones, :android)
174
- when :ipad
175
- self.user_agent = Agents.random_user_agent(:tablets, :ipad)
176
- when :android_tablet
177
- self.user_agent = Agents.random_user_agent(:tablets, :android)
178
- else
179
- self.user_agent = Agents.random_user_agent(self.device)
180
- end
181
- end
182
- end
183
-
184
- def runs_ios?
185
- Agents.runs_ios?(self.user_agent)
186
- end
187
-
188
- def is_iphone?
189
- Agents.is_iphone?(self.user_agent)
190
- end
191
-
192
- def is_ipad?
193
- Agents.is_ipad?(self.user_agent)
194
- end
195
-
196
- # Resolution
197
- def set_resolution(res)
198
- if res && res.is_a?(Array)
199
- self.resolution = res
200
- elsif res && res.is_a?(Symbol) && res.eql?(:randomize)
201
- self.resolution = randomize_resolution
202
- end
203
- end
204
-
205
- def randomize_resolution
206
- runs_ios? ? randomize_ios_resolution : Browsed::Constants::RESOLUTIONS.fetch(self.device, :desktop).sample
207
- end
208
-
209
- def randomize_ios_resolution
210
- resolution_device = case self.device
211
- when :iphone, :android_phone
212
- :phone
213
- when :ipad, :android_tablet
214
- :tablet
215
- else
216
- self.device
217
- end
218
-
219
- random_key = Browsed::Constants::RESOLUTIONS.fetch(resolution_device, :desktop).keys.sample
220
- resolution = Browsed::Constants::RESOLUTIONS.fetch(resolution_device, :desktop)[random_key]
221
- end
222
-
223
- def wait_for_ajax
224
- Timeout.timeout(Capybara.default_max_wait_time) do
225
- loop until finished_all_ajax_requests?
226
- end
227
- end
228
-
229
- def finished_all_ajax_requests?
230
- evald = self.session.evaluate_script('jQuery.active')
231
- evald.nil? || evald.zero?
232
- end
233
151
 
234
152
  def log(message)
235
153
  puts "[Browsed::Client] - #{Time.now}: #{message}" if self.configuration.verbose?