browsed 0.2.5 → 0.2.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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?