arachni 1.2.1 → 1.3

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 (373) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +66 -0
  3. data/Gemfile +1 -1
  4. data/README.md +16 -5
  5. data/components/checks/active/ldap_injection/errors.txt +1 -0
  6. data/components/checks/active/source_code_disclosure.rb +1 -1
  7. data/components/checks/active/unvalidated_redirect.rb +6 -6
  8. data/components/checks/active/unvalidated_redirect_dom.rb +10 -7
  9. data/components/checks/passive/grep/captcha.rb +14 -5
  10. data/components/checks/passive/grep/form_upload.rb +7 -3
  11. data/components/checks/passive/grep/hsts.rb +3 -3
  12. data/components/checks/passive/grep/html_objects.rb +2 -3
  13. data/components/checks/passive/grep/http_only_cookies.rb +2 -3
  14. data/components/checks/passive/grep/insecure_cookies.rb +1 -1
  15. data/components/checks/passive/grep/password_autocomplete.rb +2 -2
  16. data/components/checks/passive/grep/unencrypted_password_forms.rb +7 -7
  17. data/components/checks/passive/grep/x_frame_options.rb +2 -2
  18. data/components/checks/passive/http_put.rb +2 -3
  19. data/components/path_extractors/comments.rb +3 -3
  20. data/components/path_extractors/scripts.rb +10 -1
  21. data/components/plugins/defaults/autothrottle.rb +27 -18
  22. data/components/plugins/defaults/meta/remedies/discovery.rb +30 -33
  23. data/components/plugins/defaults/meta/remedies/timing_attacks.rb +7 -11
  24. data/components/plugins/login_script.rb +9 -3
  25. data/components/plugins/proxy.rb +4 -3
  26. data/components/reporters/html.rb +11 -14
  27. data/components/reporters/html/default/issue.erb +13 -38
  28. data/components/reporters/html/default/issue/info.erb +1 -1
  29. data/components/reporters/html/default/summary/issues/by_name.erb +3 -3
  30. data/components/reporters/stdout.rb +62 -71
  31. data/components/reporters/xml.rb +26 -40
  32. data/components/reporters/xml/schema.xsd +43 -89
  33. data/lib/arachni/browser.rb +52 -3
  34. data/lib/arachni/browser/javascript.rb +3 -3
  35. data/lib/arachni/browser/javascript/scripts/taint_tracer.js +46 -25
  36. data/lib/arachni/browser_cluster.rb +61 -0
  37. data/lib/arachni/browser_cluster/job.rb +21 -1
  38. data/lib/arachni/browser_cluster/jobs/browser_provider.rb +3 -1
  39. data/lib/arachni/browser_cluster/jobs/resource_exploration.rb +2 -1
  40. data/lib/arachni/browser_cluster/jobs/resource_exploration/event_trigger.rb +2 -1
  41. data/lib/arachni/browser_cluster/jobs/taint_trace.rb +3 -2
  42. data/lib/arachni/browser_cluster/jobs/taint_trace/event_trigger.rb +1 -1
  43. data/lib/arachni/browser_cluster/worker.rb +5 -0
  44. data/lib/arachni/check/auditor.rb +22 -12
  45. data/lib/arachni/data/framework.rb +13 -1
  46. data/lib/arachni/data/issues.rb +9 -25
  47. data/lib/arachni/element/base.rb +9 -3
  48. data/lib/arachni/element/capabilities/analyzable.rb +2 -6
  49. data/lib/arachni/element/capabilities/analyzable/differential.rb +24 -7
  50. data/lib/arachni/element/capabilities/analyzable/{taint.rb → signature.rb} +23 -23
  51. data/lib/arachni/element/capabilities/auditable.rb +0 -6
  52. data/lib/arachni/element/capabilities/dom_only.rb +61 -0
  53. data/lib/arachni/element/capabilities/with_dom.rb +3 -1
  54. data/lib/arachni/element/cookie.rb +35 -5
  55. data/lib/arachni/element/cookie/dom.rb +13 -4
  56. data/lib/arachni/element/{capabilities/auditable/dom.rb → dom.rb} +20 -68
  57. data/lib/arachni/element/dom/capabilities/auditable.rb +29 -0
  58. data/lib/arachni/element/dom/capabilities/inputtable.rb +27 -0
  59. data/lib/arachni/element/dom/capabilities/mutable.rb +21 -0
  60. data/lib/arachni/element/dom/capabilities/submittable.rb +52 -0
  61. data/lib/arachni/element/form.rb +12 -1
  62. data/lib/arachni/element/form/capabilities/mutable.rb +2 -1
  63. data/lib/arachni/element/form/capabilities/with_dom.rb +0 -1
  64. data/lib/arachni/element/form/dom.rb +9 -3
  65. data/lib/arachni/element/header.rb +14 -33
  66. data/lib/arachni/element/header/capabilities/inputtable.rb +29 -0
  67. data/lib/arachni/element/header/capabilities/mutable.rb +51 -0
  68. data/lib/arachni/element/input/dom.rb +71 -0
  69. data/lib/arachni/element/json.rb +2 -0
  70. data/lib/arachni/element/link.rb +3 -0
  71. data/lib/arachni/element/link/capabilities/with_dom.rb +0 -1
  72. data/lib/arachni/element/link/dom.rb +16 -3
  73. data/lib/arachni/element/link/dom/capabilities/submittable.rb +29 -0
  74. data/lib/arachni/element/link_template.rb +3 -5
  75. data/lib/arachni/element/link_template/capabilities/inputtable.rb +5 -0
  76. data/lib/arachni/element/link_template/capabilities/with_dom.rb +0 -1
  77. data/lib/arachni/element/link_template/dom.rb +16 -3
  78. data/lib/arachni/element/link_template/dom/capabilities/submittable.rb +29 -0
  79. data/lib/arachni/element/server.rb +3 -5
  80. data/lib/arachni/element/ui_form.rb +106 -0
  81. data/lib/arachni/element/ui_form/dom.rb +107 -0
  82. data/lib/arachni/element/ui_input.rb +62 -0
  83. data/lib/arachni/element/xml.rb +2 -1
  84. data/lib/arachni/framework.rb +7 -5
  85. data/lib/arachni/framework/parts/audit.rb +0 -1
  86. data/lib/arachni/framework/parts/check.rb +1 -0
  87. data/lib/arachni/framework/parts/data.rb +4 -0
  88. data/lib/arachni/framework/parts/state.rb +0 -2
  89. data/lib/arachni/http/client.rb +17 -6
  90. data/lib/arachni/http/proxy_server.rb +52 -5
  91. data/lib/arachni/http/request.rb +1 -1
  92. data/lib/arachni/issue.rb +34 -179
  93. data/lib/arachni/issue/severity.rb +2 -0
  94. data/lib/arachni/option_groups/audit.rb +22 -2
  95. data/lib/arachni/option_groups/browser_cluster.rb +15 -0
  96. data/lib/arachni/page.rb +3 -2
  97. data/lib/arachni/parser.rb +24 -5
  98. data/lib/arachni/platform/manager.rb +1 -2
  99. data/lib/arachni/rpc/server/framework.rb +3 -4
  100. data/lib/arachni/rpc/server/framework/multi_instance.rb +2 -1
  101. data/lib/arachni/session.rb +1 -1
  102. data/lib/arachni/trainer.rb +4 -7
  103. data/lib/arachni/watir/element.rb +12 -1
  104. data/lib/version +1 -1
  105. data/spec/arachni/browser/element_locator_spec.rb +43 -43
  106. data/spec/arachni/browser/javascript/dom_monitor_spec.rb +44 -44
  107. data/spec/arachni/browser/javascript/proxy/stub_spec.rb +17 -14
  108. data/spec/arachni/browser/javascript/proxy_spec.rb +24 -24
  109. data/spec/arachni/browser/javascript/taint_tracer/frame/called_function_spec.rb +11 -11
  110. data/spec/arachni/browser/javascript/taint_tracer/frame_spec.rb +7 -7
  111. data/spec/arachni/browser/javascript/taint_tracer/sink/data_flow_spec.rb +13 -13
  112. data/spec/arachni/browser/javascript/taint_tracer/sink/execution_flow_spec.rb +7 -7
  113. data/spec/arachni/browser/javascript/taint_tracer_spec.rb +568 -558
  114. data/spec/arachni/browser/javascript_spec.rb +73 -63
  115. data/spec/arachni/browser_cluster/job/result_spec.rb +3 -3
  116. data/spec/arachni/browser_cluster/job_spec.rb +68 -48
  117. data/spec/arachni/browser_cluster/jobs/resource_exploration/event_trigger/result_spec.rb +2 -2
  118. data/spec/arachni/browser_cluster/jobs/resource_exploration/event_trigger_spec.rb +5 -4
  119. data/spec/arachni/browser_cluster/jobs/resource_exploration/result_spec.rb +2 -2
  120. data/spec/arachni/browser_cluster/jobs/resource_exploration_spec.rb +5 -5
  121. data/spec/arachni/browser_cluster/worker_spec.rb +87 -70
  122. data/spec/arachni/browser_cluster_spec.rb +64 -39
  123. data/spec/arachni/browser_spec.rb +692 -527
  124. data/spec/arachni/check/auditor_spec.rb +177 -147
  125. data/spec/arachni/check/base_spec.rb +33 -33
  126. data/spec/arachni/check/manager_spec.rb +15 -15
  127. data/spec/arachni/component/base_spec.rb +8 -8
  128. data/spec/arachni/component/manager_spec.rb +100 -99
  129. data/spec/arachni/component/options/address_spec.rb +3 -3
  130. data/spec/arachni/component/options/base_spec.rb +7 -7
  131. data/spec/arachni/component/options/bool_spec.rb +9 -9
  132. data/spec/arachni/component/options/float_spec.rb +6 -6
  133. data/spec/arachni/component/options/int_spec.rb +5 -5
  134. data/spec/arachni/component/options/multiple_choice_spec.rb +12 -12
  135. data/spec/arachni/component/options/object_spec.rb +2 -2
  136. data/spec/arachni/component/options/path_spec.rb +3 -3
  137. data/spec/arachni/component/options/port_spec.rb +5 -5
  138. data/spec/arachni/component/options/string_spec.rb +3 -3
  139. data/spec/arachni/component/options/url_spec.rb +4 -4
  140. data/spec/arachni/component/utilities_spec.rb +2 -2
  141. data/spec/arachni/data/framework/rpc_spec.rb +10 -9
  142. data/spec/arachni/data/framework_spec.rb +65 -46
  143. data/spec/arachni/data/issues_spec.rb +39 -77
  144. data/spec/arachni/data/plugins_spec.rb +11 -11
  145. data/spec/arachni/data/session_spec.rb +6 -6
  146. data/spec/arachni/data_spec.rb +8 -8
  147. data/spec/arachni/element/body_spec.rb +10 -10
  148. data/spec/arachni/element/capabilities/analyzable/differential_spec.rb +39 -21
  149. data/spec/arachni/element/capabilities/analyzable/{taint_spec.rb → signature_spec.rb} +63 -63
  150. data/spec/arachni/element/capabilities/analyzable/timeout_spec.rb +51 -51
  151. data/spec/arachni/element/capabilities/with_scope/scope_spec.rb +5 -5
  152. data/spec/arachni/element/cookie/dom_spec.rb +37 -18
  153. data/spec/arachni/element/cookie_spec.rb +206 -139
  154. data/spec/arachni/element/form/dom_spec.rb +36 -19
  155. data/spec/arachni/element/form_spec.rb +210 -187
  156. data/spec/arachni/element/generic_dom_spec.rb +14 -14
  157. data/spec/arachni/element/header_spec.rb +35 -17
  158. data/spec/arachni/element/json_spec.rb +53 -31
  159. data/spec/arachni/element/link/dom_spec.rb +46 -28
  160. data/spec/arachni/element/link_spec.rb +58 -40
  161. data/spec/arachni/element/link_template/dom_spec.rb +47 -29
  162. data/spec/arachni/element/link_template_spec.rb +79 -61
  163. data/spec/arachni/element/path_spec.rb +1 -1
  164. data/spec/arachni/element/server_spec.rb +33 -32
  165. data/spec/arachni/element/ui_form/ui_form_dom_spec.rb +164 -0
  166. data/spec/arachni/element/ui_form_spec.rb +242 -0
  167. data/spec/arachni/element/ui_input/dom_spec.rb +157 -0
  168. data/spec/arachni/element/ui_input_spec.rb +136 -0
  169. data/spec/arachni/element/xml_spec.rb +42 -24
  170. data/spec/arachni/element_filter_spec.rb +49 -48
  171. data/spec/arachni/error_spec.rb +3 -3
  172. data/spec/arachni/framework/parts/audit_spec.rb +64 -63
  173. data/spec/arachni/framework/parts/browser_spec.rb +16 -16
  174. data/spec/arachni/framework/parts/check_spec.rb +3 -3
  175. data/spec/arachni/framework/parts/data_spec.rb +48 -48
  176. data/spec/arachni/framework/parts/platform_spec.rb +3 -3
  177. data/spec/arachni/framework/parts/plugin_spec.rb +7 -6
  178. data/spec/arachni/framework/parts/report_spec.rb +7 -7
  179. data/spec/arachni/framework/parts/scope_spec.rb +16 -16
  180. data/spec/arachni/framework/parts/state_spec.rb +68 -69
  181. data/spec/arachni/framework_spec.rb +39 -31
  182. data/spec/arachni/http/client/dynamic_404_handlers_spec.rb +32 -32
  183. data/spec/arachni/http/client_spec.rb +219 -208
  184. data/spec/arachni/http/cookie_jar_spec.rb +72 -72
  185. data/spec/arachni/http/headers_spec.rb +14 -14
  186. data/spec/arachni/http/proxy_server_spec.rb +43 -42
  187. data/spec/arachni/http/request_spec.rb +105 -103
  188. data/spec/arachni/http/response/scope_spec.rb +24 -24
  189. data/spec/arachni/http/response_spec.rb +50 -49
  190. data/spec/arachni/issue/severity_spec.rb +10 -9
  191. data/spec/arachni/issue_spec.rb +71 -369
  192. data/spec/arachni/option_groups/audit_spec.rb +114 -114
  193. data/spec/arachni/option_groups/browser_cluster_spec.rb +20 -3
  194. data/spec/arachni/option_groups/datastore_spec.rb +6 -6
  195. data/spec/arachni/option_groups/dispatcher_spec.rb +19 -19
  196. data/spec/arachni/option_groups/http_spec.rb +11 -11
  197. data/spec/arachni/option_groups/input_spec.rb +31 -27
  198. data/spec/arachni/option_groups/output_spec.rb +2 -2
  199. data/spec/arachni/option_groups/paths_spec.rb +17 -17
  200. data/spec/arachni/option_groups/rpc_spec.rb +2 -2
  201. data/spec/arachni/option_groups/scope_spec.rb +40 -40
  202. data/spec/arachni/option_groups/session_spec.rb +6 -5
  203. data/spec/arachni/option_groups/snapshot_spec.rb +4 -4
  204. data/spec/arachni/options_spec.rb +46 -45
  205. data/spec/arachni/page/dom/transition_spec.rb +74 -72
  206. data/spec/arachni/page/dom_spec.rb +35 -35
  207. data/spec/arachni/page/scope_spec.rb +15 -15
  208. data/spec/arachni/page_spec.rb +217 -217
  209. data/spec/arachni/parser_spec.rb +106 -104
  210. data/spec/arachni/platform/fingerprinter_spec.rb +17 -14
  211. data/spec/arachni/platform/list_spec.rb +33 -33
  212. data/spec/arachni/platform/manager_spec.rb +67 -64
  213. data/spec/arachni/plugin/base_spec.rb +10 -10
  214. data/spec/arachni/plugin/manager_spec.rb +38 -37
  215. data/spec/arachni/report_spec.rb +43 -40
  216. data/spec/arachni/reporter/base_spec.rb +15 -15
  217. data/spec/arachni/reporter/manager_spec.rb +4 -4
  218. data/spec/arachni/reporter/options_spec.rb +6 -6
  219. data/spec/arachni/rpc/client/base_spec.rb +6 -6
  220. data/spec/arachni/rpc/client/dispatcher_spec.rb +2 -2
  221. data/spec/arachni/rpc/client/instance_spec.rb +6 -6
  222. data/spec/arachni/rpc/server/active_options_spec.rb +11 -8
  223. data/spec/arachni/rpc/server/base_spec.rb +5 -5
  224. data/spec/arachni/rpc/server/checks/manager_spec.rb +8 -8
  225. data/spec/arachni/rpc/server/dispatcher/node_spec.rb +37 -37
  226. data/spec/arachni/rpc/server/dispatcher/service_spec.rb +15 -14
  227. data/spec/arachni/rpc/server/dispatcher_spec.rb +36 -35
  228. data/spec/arachni/rpc/server/framework/distributor_spec.rb +36 -36
  229. data/spec/arachni/rpc/server/framework_multi_spec.rb +340 -336
  230. data/spec/arachni/rpc/server/framework_spec.rb +90 -85
  231. data/spec/arachni/rpc/server/instance_spec.rb +126 -107
  232. data/spec/arachni/rpc/server/output_spec.rb +1 -1
  233. data/spec/arachni/rpc/server/plugin/manager_spec.rb +6 -6
  234. data/spec/arachni/ruby/array_spec.rb +42 -42
  235. data/spec/arachni/ruby/hash_spec.rb +20 -18
  236. data/spec/arachni/ruby/io_spec.rb +2 -2
  237. data/spec/arachni/ruby/object_spec.rb +1 -1
  238. data/spec/arachni/ruby/set_spec.rb +3 -3
  239. data/spec/arachni/ruby/string_spec.rb +30 -30
  240. data/spec/arachni/ruby/webrick_spec.rb +2 -2
  241. data/spec/arachni/scope_spec.rb +1 -1
  242. data/spec/arachni/session_spec.rb +67 -64
  243. data/spec/arachni/snapshot_spec.rb +15 -15
  244. data/spec/arachni/state/audit_spec.rb +11 -11
  245. data/spec/arachni/state/element_filter_spec.rb +6 -6
  246. data/spec/arachni/state/framework/rpc_spec.rb +12 -12
  247. data/spec/arachni/state/framework_spec.rb +125 -121
  248. data/spec/arachni/state/http_spec.rb +7 -7
  249. data/spec/arachni/state/options_spec.rb +7 -7
  250. data/spec/arachni/state/plugins_spec.rb +8 -8
  251. data/spec/arachni/state_spec.rb +10 -10
  252. data/spec/arachni/support/buffer/autoflush_spec.rb +16 -16
  253. data/spec/arachni/support/buffer/base_spec.rb +39 -39
  254. data/spec/arachni/support/cache/least_cost_replacement_spec.rb +18 -18
  255. data/spec/arachni/support/cache/least_recently_pushed_spec.rb +24 -24
  256. data/spec/arachni/support/cache/least_recently_used_spec.rb +20 -20
  257. data/spec/arachni/support/cache/preference_spec.rb +4 -4
  258. data/spec/arachni/support/cache/random_replacement_spec.rb +8 -8
  259. data/spec/arachni/support/crypto/rsa_aes_cbc_spec.rb +1 -1
  260. data/spec/arachni/support/database/hash_spec.rb +44 -43
  261. data/spec/arachni/support/database/queue_spec.rb +27 -27
  262. data/spec/arachni/support/lookup/hash_set_spec.rb +8 -8
  263. data/spec/arachni/support/lookup/moolb_spec.rb +3 -3
  264. data/spec/arachni/support/mixins/observable_spec.rb +6 -6
  265. data/spec/arachni/support/signature_spec.rb +19 -19
  266. data/spec/arachni/trainer_spec.rb +39 -39
  267. data/spec/arachni/typhoeus/hydra_spec.rb +2 -2
  268. data/spec/arachni/uri/scope_spec.rb +66 -66
  269. data/spec/arachni/uri_spec.rb +107 -105
  270. data/spec/arachni/utilities_spec.rb +40 -40
  271. data/spec/components/checks/active/csrf_spec.rb +8 -8
  272. data/spec/components/checks/active/no_sql_injection_spec.rb +1 -1
  273. data/spec/components/checks/active/sql_injection_spec.rb +16 -16
  274. data/spec/components/checks/active/trainer_spec.rb +4 -4
  275. data/spec/components/checks/active/unvalidated_redirect_dom_spec.rb +4 -2
  276. data/spec/components/checks/active/xpath_injection_spec.rb +1 -1
  277. data/spec/components/checks/active/xss_dom_script_context_spec.rb +51 -21
  278. data/spec/components/checks/active/xss_dom_spec.rb +46 -24
  279. data/spec/components/checks/passive/allowed_methods_spec.rb +1 -1
  280. data/spec/components/checks/passive/grep/cookie_set_for_parent_domain_spec.rb +1 -1
  281. data/spec/components/checks/passive/grep/hsts_spec.rb +2 -2
  282. data/spec/components/checks/passive/grep/http_only_cookies_spec.rb +1 -1
  283. data/spec/components/checks/passive/grep/insecure_cookies_spec.rb +1 -1
  284. data/spec/components/checks/passive/grep/insecure_cors_policy_spec.rb +2 -2
  285. data/spec/components/checks/passive/grep/password_autocomplete_spec.rb +1 -1
  286. data/spec/components/checks/passive/grep/private_ip_spec.rb +3 -3
  287. data/spec/components/checks/passive/grep/unencrypted_password_forms_spec.rb +1 -1
  288. data/spec/components/checks/passive/grep/x_frame_options_spec.rb +2 -2
  289. data/spec/components/checks/passive/interesting_responses_spec.rb +2 -2
  290. data/spec/components/checks/passive/webdav_spec.rb +1 -1
  291. data/spec/components/checks/passive/xst_spec.rb +1 -1
  292. data/spec/components/fingerprinters/servers/apache_spec.rb +2 -2
  293. data/spec/components/path_extractors/comments_spec.rb +5 -1
  294. data/spec/components/path_extractors/scripts_spec.rb +5 -2
  295. data/spec/components/plugins/autologin_spec.rb +22 -22
  296. data/spec/components/plugins/autothrottle_spec.rb +6 -5
  297. data/spec/components/plugins/content_types_spec.rb +4 -4
  298. data/spec/components/plugins/cookie_collector_spec.rb +5 -5
  299. data/spec/components/plugins/exec_spec.rb +12 -12
  300. data/spec/components/plugins/form_dicattack_spec.rb +3 -3
  301. data/spec/components/plugins/headers_collector_spec.rb +8 -8
  302. data/spec/components/plugins/healthmap_spec.rb +3 -3
  303. data/spec/components/plugins/http_dicattack_spec.rb +3 -3
  304. data/spec/components/plugins/login_script_spec.rb +79 -22
  305. data/spec/components/plugins/meta/remedies/discovery_spec.rb +3 -2
  306. data/spec/components/plugins/meta/remedies/timing_attacks_spec.rb +3 -3
  307. data/spec/components/plugins/meta/uniformity_spec.rb +2 -2
  308. data/spec/components/plugins/restrict_to_dom_state_spec.rb +1 -1
  309. data/spec/components/plugins/script_spec.rb +1 -1
  310. data/spec/components/plugins/uncommon_headers_spec.rb +2 -2
  311. data/spec/components/plugins/vector_collector_spec.rb +2 -2
  312. data/spec/components/plugins/vector_feed_spec.rb +40 -40
  313. data/spec/components/plugins/waf_detector_spec.rb +6 -6
  314. data/spec/components/reporters/json_spec.rb +4 -4
  315. data/spec/components/reporters/marshal_spec.rb +2 -2
  316. data/spec/components/reporters/yaml_spec.rb +3 -2
  317. data/spec/external/wavsep/active/sqli_spec.rb +1 -3
  318. data/spec/spec_helper.rb +4 -0
  319. data/spec/support/factories/element/ui_form.rb +14 -0
  320. data/spec/support/factories/element/ui_input.rb +13 -0
  321. data/spec/support/factories/issue.rb +0 -13
  322. data/spec/support/fixtures/report.afr +0 -0
  323. data/spec/support/fixtures/{taint_check/taint.rb → signature_check/signature.rb} +2 -2
  324. data/spec/support/helpers/browser_cluster/jobs/taint_tracer.rb +11 -11
  325. data/spec/support/helpers/framework.rb +1 -1
  326. data/spec/support/helpers/pages.rb +2 -2
  327. data/spec/support/servers/arachni/browser.rb +139 -0
  328. data/spec/support/servers/arachni/browser/javascript/taint_tracer.rb +40 -0
  329. data/spec/support/servers/arachni/element/capabilities/analyzable/{taint.rb → signature.rb} +0 -0
  330. data/spec/support/servers/arachni/element/input/input_dom.rb +102 -0
  331. data/spec/support/servers/arachni/element/ui_form/ui_form_dom.rb +238 -0
  332. data/spec/support/servers/checks/active/trainer_check.rb +7 -7
  333. data/spec/support/servers/checks/active/unvalidated_redirect_dom.rb +22 -6
  334. data/spec/support/servers/checks/active/xss_dom.rb +50 -0
  335. data/spec/support/servers/checks/active/xss_dom_script_context.rb +53 -0
  336. data/spec/support/shared/browser/javascript/taint_tracer/sink/base.rb +6 -6
  337. data/spec/support/shared/check.rb +10 -12
  338. data/spec/support/shared/component/options/base.rb +24 -24
  339. data/spec/support/shared/element/base.rb +25 -25
  340. data/spec/support/shared/element/capabilities/auditable.rb +116 -140
  341. data/spec/support/shared/element/capabilities/dom_only.rb +65 -0
  342. data/spec/support/shared/element/capabilities/inputtable.rb +71 -86
  343. data/spec/support/shared/element/capabilities/mutable.rb +122 -111
  344. data/spec/support/shared/element/capabilities/refreshable.rb +10 -10
  345. data/spec/support/shared/element/capabilities/{submitable.rb → submittable.rb} +26 -26
  346. data/spec/support/shared/element/capabilities/with_auditor.rb +10 -10
  347. data/spec/support/shared/element/capabilities/with_dom.rb +8 -8
  348. data/spec/support/shared/element/capabilities/with_node.rb +4 -6
  349. data/spec/support/shared/element/capabilities/with_scope.rb +2 -2
  350. data/spec/support/shared/element/capabilities/with_source.rb +6 -8
  351. data/spec/support/shared/element/dom.rb +144 -0
  352. data/spec/support/shared/element/dom/auditable.rb +42 -0
  353. data/spec/support/shared/element/dom/inputtable.rb +5 -0
  354. data/spec/support/shared/element/dom/mutable.rb +3 -0
  355. data/spec/support/shared/element/dom/submittable.rb +119 -0
  356. data/spec/support/shared/external/wavsep.rb +3 -3
  357. data/spec/support/shared/fingerprinter.rb +2 -2
  358. data/spec/support/shared/framework.rb +1 -1
  359. data/spec/support/shared/http/message.rb +9 -9
  360. data/spec/support/shared/option_group.rb +17 -17
  361. data/spec/support/shared/path_extractor.rb +1 -1
  362. data/spec/support/shared/plugin.rb +2 -2
  363. data/spec/support/shared/support/cache.rb +57 -57
  364. data/spec/support/shared/support/lookup.rb +25 -25
  365. data/ui/cli/framework.rb +22 -11
  366. data/ui/cli/framework/option_parser.rb +15 -0
  367. data/ui/cli/option_parser.rb +8 -1
  368. data/ui/cli/output.rb +2 -1
  369. metadata +54 -20
  370. data/components/checks/active/xss_dom_inputs.rb +0 -236
  371. data/spec/components/checks/active/xss_dom_inputs_spec.rb +0 -30
  372. data/spec/support/servers/checks/active/xss_dom_inputs.rb +0 -59
  373. data/spec/support/shared/element/capabilities/auditable/dom.rb +0 -322
@@ -15,19 +15,21 @@ class MockWorker
15
15
  end
16
16
 
17
17
  class JobTest < Arachni::BrowserCluster::Job
18
+ include RSpec::Matchers
19
+
18
20
  def ran?
19
21
  !!@ran
20
22
  end
21
23
 
22
24
  def run
23
- browser.class.should == MockWorker
25
+ expect(browser.class).to eq MockWorker
24
26
  @ran = true
25
27
  end
26
28
  end
27
29
 
28
30
  class JobConfigureAndRunTest < JobTest
29
31
  def run
30
- browser.class.should == MockWorker
32
+ expect(browser.class).to eq MockWorker
31
33
  super
32
34
  end
33
35
  end
@@ -42,8 +44,8 @@ class JobSaveResultTest < JobTest
42
44
  save_result my_data: val
43
45
 
44
46
  result = browser.master.result
45
- result.job.id.should == self.id
46
- result.my_data.should == val
47
+ expect(result.job.id).to eq self.id
48
+ expect(result.my_data).to eq val
47
49
 
48
50
  super
49
51
  end
@@ -51,13 +53,13 @@ end
51
53
 
52
54
  class JobCleanCopyTest < JobTest
53
55
  def run
54
- browser.class.should == MockWorker
56
+ expect(browser.class).to eq MockWorker
55
57
 
56
58
  copy = self.clean_copy
57
- copy.browser.should == nil
58
- copy.id.should == self.id
59
+ expect(copy.browser).to eq nil
60
+ expect(copy.id).to eq self.id
59
61
 
60
- browser.class.should == MockWorker
62
+ expect(browser.class).to eq MockWorker
61
63
 
62
64
  super
63
65
  end
@@ -89,7 +91,7 @@ describe Arachni::BrowserCluster::Job do
89
91
  id = described_class.new.id
90
92
  next if i == 0
91
93
 
92
- described_class.new.id.should == id + 1
94
+ expect(described_class.new.id).to eq(id + 1)
93
95
  end
94
96
  end
95
97
  end
@@ -101,20 +103,20 @@ describe Arachni::BrowserCluster::Job do
101
103
  context true do
102
104
  it 'returns true' do
103
105
  subject.never_ending = true
104
- subject.never_ending?.should be_true
106
+ expect(subject.never_ending?).to be_truthy
105
107
  end
106
108
  end
107
109
 
108
110
  context false do
109
111
  it 'returns false' do
110
112
  subject.never_ending = false
111
- subject.never_ending?.should be_false
113
+ expect(subject.never_ending?).to be_falsey
112
114
  end
113
115
  end
114
116
 
115
117
  context nil do
116
118
  it 'returns false' do
117
- subject.never_ending?.should be_false
119
+ expect(subject.never_ending?).to be_falsey
118
120
  end
119
121
  end
120
122
  end
@@ -128,16 +130,16 @@ describe Arachni::BrowserCluster::Job do
128
130
  end
129
131
 
130
132
  it 'calls #run' do
131
- subject.ran?.should be_false
133
+ expect(subject.ran?).to be_falsey
132
134
  subject.configure_and_run( worker )
133
- subject.ran?.should be_true
135
+ expect(subject.ran?).to be_truthy
134
136
  end
135
137
 
136
138
  it 'removes #browser' do
137
- subject.ran?.should be_false
139
+ expect(subject.ran?).to be_falsey
138
140
  subject.configure_and_run( worker )
139
- subject.browser.should be_nil
140
- subject.ran?.should be_true
141
+ expect(subject.browser).to be_nil
142
+ expect(subject.ran?).to be_truthy
141
143
  end
142
144
  end
143
145
 
@@ -145,9 +147,9 @@ describe Arachni::BrowserCluster::Job do
145
147
  subject { JobSaveResultTest.new }
146
148
 
147
149
  it 'forwards the result to the BrowserCluster' do
148
- subject.ran?.should be_false
150
+ expect(subject.ran?).to be_falsey
149
151
  subject.configure_and_run( worker )
150
- subject.ran?.should be_true
152
+ expect(subject.ran?).to be_truthy
151
153
  end
152
154
  end
153
155
 
@@ -155,9 +157,9 @@ describe Arachni::BrowserCluster::Job do
155
157
  subject { JobCleanCopyTest.new }
156
158
 
157
159
  it 'copies the Job without the resources set by #configure_and_run' do
158
- subject.ran?.should be_false
160
+ expect(subject.ran?).to be_falsey
159
161
  subject.configure_and_run( worker )
160
- subject.ran?.should be_true
162
+ expect(subject.ran?).to be_truthy
161
163
  end
162
164
  end
163
165
 
@@ -165,11 +167,29 @@ describe Arachni::BrowserCluster::Job do
165
167
  subject { JobDupTest.new( never_ending: true, my_data: 'stuff' ) }
166
168
 
167
169
  it 'copies the Job' do
168
- subject.my_data.should == 'stuff'
170
+ expect(subject.my_data).to eq('stuff')
171
+
172
+ dup = subject.dup
173
+ expect(dup.my_data).to eq('stuff')
174
+ expect(dup.never_ending?).to eq(true)
175
+ end
176
+
177
+ it 'preserves #time' do
178
+ subject.time = 10
179
+ expect(subject.time).to eq 10
180
+
181
+ dup = subject.dup
182
+ expect(dup.time).to eq 10
183
+ end
184
+
185
+ it 'preserves #timed_out' do
186
+ subject.timed_out! 10
187
+ expect(subject.time).to eq 10
188
+ expect(subject).to be_timed_out
169
189
 
170
190
  dup = subject.dup
171
- dup.my_data.should == 'stuff'
172
- dup.never_ending?.should == true
191
+ expect(dup.time).to eq 10
192
+ expect(subject).to be_timed_out
173
193
  end
174
194
  end
175
195
 
@@ -178,33 +198,33 @@ describe Arachni::BrowserCluster::Job do
178
198
 
179
199
  it 'sets the original Job as the #forwarder' do
180
200
  id = subject.id
181
- subject.forward.forwarder.should == subject
201
+ expect(subject.forward.forwarder).to eq(subject)
182
202
  end
183
203
 
184
204
  it 'creates a new Job with the same #id' do
185
205
  id = subject.id
186
- subject.forward.id.should == id
206
+ expect(subject.forward.id).to eq(id)
187
207
  end
188
208
 
189
209
  it 'creates a new Job with the same #never_ending' do
190
- subject.forward.never_ending?.should be_false
210
+ expect(subject.forward.never_ending?).to be_falsey
191
211
 
192
212
  job = JobForwardTest.new( never_ending: true, my_data: 'stuff' )
193
- job.never_ending?.should be_true
194
- job.forward.never_ending?.should be_true
213
+ expect(job.never_ending?).to be_truthy
214
+ expect(job.forward.never_ending?).to be_truthy
195
215
 
196
216
  job = JobForwardTest.new( never_ending: false, my_data: 'stuff' )
197
- job.never_ending?.should be_false
198
- job.forward.never_ending?.should be_false
217
+ expect(job.never_ending?).to be_falsey
218
+ expect(job.forward.never_ending?).to be_falsey
199
219
  end
200
220
 
201
221
  it 'does not preserve any existing data' do
202
- subject.forward.my_data.should be_nil
222
+ expect(subject.forward.my_data).to be_nil
203
223
  end
204
224
 
205
225
  context 'when options are given' do
206
226
  it 'sets initialization options' do
207
- subject.forward( my_data: 'stuff2' ).my_data.should == 'stuff2'
227
+ expect(subject.forward( my_data: 'stuff2' ).my_data).to eq('stuff2')
208
228
  end
209
229
  end
210
230
  end
@@ -214,49 +234,49 @@ describe Arachni::BrowserCluster::Job do
214
234
 
215
235
  it 'sets the original Job as the #forwarder' do
216
236
  id = subject.id
217
- subject.forward_as( JobForwardAsTest ).forwarder.should == subject
237
+ expect(subject.forward_as( JobForwardAsTest ).forwarder).to eq(subject)
218
238
  end
219
239
 
220
240
  it 'creates a new Job type with the same #id' do
221
- subject.should_not be_kind_of JobForwardAsTest
241
+ expect(subject).not_to be_kind_of JobForwardAsTest
222
242
 
223
243
  id = subject.id
224
244
 
225
245
  forwarded = subject.forward_as( JobForwardAsTest )
226
246
 
227
- forwarded.id.should == id
228
- forwarded.should be_kind_of JobForwardAsTest
247
+ expect(forwarded.id).to eq(id)
248
+ expect(forwarded).to be_kind_of JobForwardAsTest
229
249
  end
230
250
 
231
251
  it 'creates a new Job with the same #never_ending' do
232
- subject.forward_as( JobForwardAsTest ).never_ending?.should be_false
252
+ expect(subject.forward_as( JobForwardAsTest ).never_ending?).to be_falsey
233
253
 
234
254
  job = JobForwardTest.new( never_ending: true, my_data: 'stuff' )
235
- job.never_ending?.should be_true
236
- job.forward_as( JobForwardAsTest ).never_ending?.should be_true
255
+ expect(job.never_ending?).to be_truthy
256
+ expect(job.forward_as( JobForwardAsTest ).never_ending?).to be_truthy
237
257
 
238
258
  job = JobForwardTest.new( never_ending: false, my_data: 'stuff' )
239
- job.never_ending?.should be_false
240
- job.forward_as( JobForwardAsTest ).never_ending?.should be_false
259
+ expect(job.never_ending?).to be_falsey
260
+ expect(job.forward_as( JobForwardAsTest ).never_ending?).to be_falsey
241
261
  end
242
262
 
243
263
  it 'does not preserve any existing data' do
244
- subject.should_not be_kind_of JobForwardAsTest
264
+ expect(subject).not_to be_kind_of JobForwardAsTest
245
265
 
246
266
  forwarded = subject.forward_as( JobForwardAsTest )
247
267
 
248
- forwarded.my_data.should be_nil
249
- forwarded.should be_kind_of JobForwardAsTest
268
+ expect(forwarded.my_data).to be_nil
269
+ expect(forwarded).to be_kind_of JobForwardAsTest
250
270
  end
251
271
 
252
272
  context 'when options are given' do
253
273
  it 'sets initialization options' do
254
- subject.should_not be_kind_of JobForwardAsTest
274
+ expect(subject).not_to be_kind_of JobForwardAsTest
255
275
 
256
276
  forwarded = subject.forward_as( JobForwardAsTest, my_data: 'stuff2' )
257
277
 
258
- forwarded.my_data.should == 'stuff2'
259
- forwarded.should be_kind_of JobForwardAsTest
278
+ expect(forwarded.my_data).to eq('stuff2')
279
+ expect(forwarded).to be_kind_of JobForwardAsTest
260
280
  end
261
281
  end
262
282
  end
@@ -2,6 +2,6 @@ require 'spec_helper'
2
2
 
3
3
  describe Arachni::BrowserCluster::Jobs::ResourceExploration::EventTrigger::Result do
4
4
  subject { described_class.new }
5
- it { should respond_to :page }
6
- it { should respond_to :page= }
5
+ it { is_expected.to respond_to :page }
6
+ it { is_expected.to respond_to :page= }
7
7
  end
@@ -25,17 +25,18 @@ describe Arachni::BrowserCluster::Jobs::ResourceExploration::EventTrigger do
25
25
  pages = []
26
26
 
27
27
  @cluster.queue( job ) do |result|
28
- result.should be_kind_of described_class::Result
28
+ expect(result).to be_kind_of described_class::Result
29
29
  pages << result.page
30
30
  end
31
31
  @cluster.wait
32
32
 
33
- pages.size.should == 2
33
+ expect(pages.size).to eq(2)
34
34
 
35
35
  page = pages.last
36
- page.dom.transitions.last.event.should == event
37
- Nokogiri::HTML( page.body ).xpath("//div[@id='my-div']").first.to_s.should ==
36
+ expect(page.dom.transitions.last.event).to eq(event)
37
+ expect(Nokogiri::HTML( page.body ).xpath("//div[@id='my-div']").first.to_s).to eq(
38
38
  '<div id="my-div"><a href="#3">My link</a></div>'
39
+ )
39
40
  end
40
41
 
41
42
  context 'when the resource is a' do
@@ -2,6 +2,6 @@ require 'spec_helper'
2
2
 
3
3
  describe Arachni::BrowserCluster::Jobs::ResourceExploration::Result do
4
4
  subject { described_class.new }
5
- it { should respond_to :page }
6
- it { should respond_to :page= }
5
+ it { is_expected.to respond_to :page }
6
+ it { is_expected.to respond_to :page= }
7
7
  end
@@ -15,18 +15,18 @@ describe Arachni::BrowserCluster::Jobs::ResourceExploration do
15
15
  has_event_triggers = false
16
16
 
17
17
  @cluster.queue( job ) do |result|
18
- result.should be_kind_of described_class::Result
18
+ expect(result).to be_kind_of described_class::Result
19
19
 
20
20
  if result.job.is_a? described_class::EventTrigger
21
21
  has_event_triggers = true
22
- result.job.forwarder.should be_kind_of described_class
22
+ expect(result.job.forwarder).to be_kind_of described_class
23
23
  end
24
24
 
25
25
  pages << result.page
26
26
  end
27
27
  @cluster.wait
28
28
 
29
- has_event_triggers.should be_true
29
+ expect(has_event_triggers).to be_truthy
30
30
  browser_explore_check_pages pages
31
31
  end
32
32
 
@@ -55,7 +55,7 @@ describe Arachni::BrowserCluster::Jobs::ResourceExploration do
55
55
  q << subject
56
56
 
57
57
  restored = q.pop
58
- restored.should == subject
58
+ expect(restored).to eq(subject)
59
59
  end
60
60
  end
61
61
 
@@ -73,7 +73,7 @@ describe Arachni::BrowserCluster::Jobs::ResourceExploration do
73
73
  q << subject
74
74
 
75
75
  restored = q.pop
76
- restored.should == subject
76
+ expect(restored).to eq(subject)
77
77
  end
78
78
  end
79
79
  end
@@ -29,33 +29,33 @@ describe Arachni::BrowserCluster::Worker do
29
29
  describe :job_timeout do
30
30
  it 'sets how much time to allow each job to run' do
31
31
  @worker = described_class.new( job_timeout: 10 )
32
- @worker.job_timeout.should == 10
32
+ expect(@worker.job_timeout).to eq(10)
33
33
  end
34
34
 
35
35
  it "defaults to #{Arachni::OptionGroups::BrowserCluster}#job_timeout" do
36
36
  Arachni::Options.browser_cluster.job_timeout = 5
37
37
  @worker = described_class.new
38
- @worker.job_timeout.should == 5
38
+ expect(@worker.job_timeout).to eq(5)
39
39
  end
40
40
  end
41
41
 
42
42
  describe :max_time_to_live do
43
43
  it 'sets how many jobs should be run before respawning' do
44
44
  @worker = described_class.new( max_time_to_live: 10 )
45
- @worker.max_time_to_live.should == 10
45
+ expect(@worker.max_time_to_live).to eq(10)
46
46
  end
47
47
 
48
48
  it "defaults to #{Arachni::OptionGroups::BrowserCluster}#worker_time_to_live" do
49
49
  Arachni::Options.browser_cluster.worker_time_to_live = 5
50
50
  @worker = described_class.new
51
- @worker.max_time_to_live.should == 5
51
+ expect(@worker.max_time_to_live).to eq(5)
52
52
  end
53
53
  end
54
54
  end
55
55
 
56
56
  describe '#run_job' do
57
57
  it 'processes jobs from #master' do
58
- subject.should receive(:run_job).with(custom_job)
58
+ expect(subject).to receive(:run_job).with(custom_job)
59
59
  @cluster.queue( custom_job ){}
60
60
  @cluster.wait
61
61
  end
@@ -66,7 +66,7 @@ describe Arachni::BrowserCluster::Worker do
66
66
  job = subject.job
67
67
  end
68
68
  @cluster.wait
69
- job.should == custom_job
69
+ expect(job).to eq(custom_job)
70
70
  end
71
71
 
72
72
  context 'before running the job' do
@@ -78,24 +78,24 @@ describe Arachni::BrowserCluster::Worker do
78
78
  @cluster.queue( custom_job ){}
79
79
  @cluster.wait
80
80
 
81
- subject.pid.should_not == dead_pid
82
- Process.getpgid( subject.pid ).should be_true
81
+ expect(subject.pid).not_to eq(dead_pid)
82
+ expect(Process.getpgid( subject.pid )).to be_truthy
83
83
  end
84
84
  end
85
85
 
86
86
  context 'when a job fails' do
87
87
  it 'ignores it' do
88
- custom_job.stub(:configure_and_run){ raise 'stuff' }
89
- subject.run_job( custom_job ).should be_true
88
+ allow(custom_job).to receive(:configure_and_run){ raise 'stuff' }
89
+ expect(subject.run_job( custom_job )).to be_truthy
90
90
  end
91
91
 
92
92
  context Selenium::WebDriver::Error::WebDriverError do
93
93
  it 'respawns' do
94
- subject.watir.stub(:cookies) do
94
+ allow(subject.watir).to receive(:cookies) do
95
95
  raise Selenium::WebDriver::Error::WebDriverError
96
96
  end
97
97
 
98
- subject.watir.stub(:close) do
98
+ allow(subject.watir).to receive(:close) do
99
99
  raise Selenium::WebDriver::Error::WebDriverError
100
100
  end
101
101
 
@@ -104,8 +104,8 @@ describe Arachni::BrowserCluster::Worker do
104
104
 
105
105
  subject.run_job( custom_job )
106
106
 
107
- watir.should_not == subject.watir
108
- pid.should_not == subject.pid
107
+ expect(watir).not_to eq(subject.watir)
108
+ expect(pid).not_to eq(subject.pid)
109
109
  end
110
110
  end
111
111
  end
@@ -113,79 +113,46 @@ describe Arachni::BrowserCluster::Worker do
113
113
  context 'when the job finishes' do
114
114
  let(:page) { Arachni::Page.from_url(url) }
115
115
 
116
- context 'when there are 5 or more windows open' do
117
- before(:each) do
118
- 5.times do
119
- subject.javascript.run( 'window.open()' )
120
- end
121
- end
122
-
123
- it 'respawns PhantomJS' do
124
- watir = subject.watir
125
- pid = subject.pid
126
-
127
- subject.watir.windows.size.should > 5
128
- @cluster.explore( page ) {}
129
- @cluster.wait
130
-
131
- watir.should_not == subject.watir
132
- pid.should_not == subject.pid
133
- subject.watir.windows.size.should == 2
134
- end
135
-
136
- it 'clears the cached HTTP responses' do
137
- subject.preload page
138
- subject.preloads.should be_any
139
- subject.instance_variable_get(:@window_responses)
140
-
141
- subject.watir.windows.size.should > 5
142
- @cluster.queue( custom_job ) {}
143
- @cluster.wait
144
-
145
- subject.instance_variable_get(:@window_responses).should be_empty
146
- end
147
- end
148
-
149
116
  it "clears the #{Arachni::Browser::Javascript}#taint" do
150
117
  subject.javascript.taint = 'stuff'
151
118
 
152
119
  @cluster.queue( custom_job ) {}
153
120
  @cluster.wait
154
121
 
155
- subject.javascript.taint.should be_nil
122
+ expect(subject.javascript.taint).to be_nil
156
123
  end
157
124
 
158
125
  it 'clears #cookies' do
159
126
  subject.preload page
160
- subject.preloads.should be_any
127
+ expect(subject.preloads).to be_any
161
128
 
162
129
  @cluster.with_browser do |browser|
163
130
  browser.load page
164
- subject.cookies.should be_any
131
+ expect(subject.cookies).to be_any
165
132
  end
166
133
  @cluster.wait
167
134
 
168
- subject.cookies.should be_empty
135
+ expect(subject.cookies).to be_empty
169
136
  end
170
137
 
171
138
  it 'clears #preloads' do
172
139
  subject.preload page
173
- subject.preloads.should be_any
140
+ expect(subject.preloads).to be_any
174
141
 
175
142
  @cluster.queue( custom_job ) {}
176
143
  @cluster.wait
177
144
 
178
- subject.preloads.should be_empty
145
+ expect(subject.preloads).to be_empty
179
146
  end
180
147
 
181
148
  it 'clears #cache' do
182
149
  subject.cache page
183
- subject.cache.should be_any
150
+ expect(subject.cache).to be_any
184
151
 
185
152
  @cluster.queue( custom_job ) {}
186
153
  @cluster.wait
187
154
 
188
- subject.cache.should be_empty
155
+ expect(subject.cache).to be_empty
189
156
  end
190
157
 
191
158
  it 'clears #captured_pages' do
@@ -194,7 +161,7 @@ describe Arachni::BrowserCluster::Worker do
194
161
  @cluster.queue( custom_job ) {}
195
162
  @cluster.wait
196
163
 
197
- subject.captured_pages.should be_empty
164
+ expect(subject.captured_pages).to be_empty
198
165
  end
199
166
 
200
167
  it 'clears #page_snapshots' do
@@ -203,7 +170,7 @@ describe Arachni::BrowserCluster::Worker do
203
170
  @cluster.queue( custom_job ) {}
204
171
  @cluster.wait
205
172
 
206
- subject.page_snapshots.should be_empty
173
+ expect(subject.page_snapshots).to be_empty
207
174
  end
208
175
 
209
176
  it 'clears #page_snapshots_with_sinks' do
@@ -212,7 +179,7 @@ describe Arachni::BrowserCluster::Worker do
212
179
  @cluster.queue( custom_job ) {}
213
180
  @cluster.wait
214
181
 
215
- subject.page_snapshots_with_sinks.should be_empty
182
+ expect(subject.page_snapshots_with_sinks).to be_empty
216
183
  end
217
184
 
218
185
  it 'clears #on_new_page callbacks' do
@@ -221,7 +188,7 @@ describe Arachni::BrowserCluster::Worker do
221
188
  @cluster.queue( custom_job ) {}
222
189
  @cluster.wait
223
190
 
224
- subject.observer_count_for(:on_new_page).should == 0
191
+ expect(subject.observer_count_for(:on_new_page)).to eq(0)
225
192
  end
226
193
 
227
194
  it 'clears #on_new_page_with_sink callbacks' do
@@ -230,7 +197,7 @@ describe Arachni::BrowserCluster::Worker do
230
197
  @cluster.queue( custom_job ){}
231
198
  @cluster.wait
232
199
 
233
- subject.observer_count_for(:on_new_page_with_sink).should == 0
200
+ expect(subject.observer_count_for(:on_new_page_with_sink)).to eq(0)
234
201
  end
235
202
 
236
203
  it 'clears #on_response callbacks' do
@@ -239,7 +206,7 @@ describe Arachni::BrowserCluster::Worker do
239
206
  @cluster.queue( custom_job ){}
240
207
  @cluster.wait
241
208
 
242
- subject.observer_count_for(:on_response).should == 0
209
+ expect(subject.observer_count_for(:on_response)).to eq(0)
243
210
  end
244
211
 
245
212
  it 'clears #on_fire_event callbacks' do
@@ -248,19 +215,58 @@ describe Arachni::BrowserCluster::Worker do
248
215
  @cluster.queue( custom_job ){}
249
216
  @cluster.wait
250
217
 
251
- subject.observer_count_for(:on_fire_event).should == 0
218
+ expect(subject.observer_count_for(:on_fire_event)).to eq(0)
252
219
  end
253
220
 
254
221
  it 'removes #job' do
255
222
  @cluster.queue( custom_job ){}
256
223
  @cluster.wait
257
- subject.job.should be_nil
224
+ expect(subject.job).to be_nil
258
225
  end
259
226
 
260
227
  it 'decrements #time_to_live' do
261
228
  @cluster.queue( custom_job ) {}
262
229
  @cluster.wait
263
- subject.time_to_live.should == subject.max_time_to_live - 1
230
+ expect(subject.time_to_live).to eq(subject.max_time_to_live - 1)
231
+ end
232
+
233
+ it 'sets Job#time' do
234
+ @cluster.queue( custom_job ) {}
235
+ @cluster.wait
236
+ expect(custom_job.time).to be > 0
237
+ end
238
+
239
+ context 'when there are 5 or more windows open' do
240
+ before(:each) do
241
+ 5.times do
242
+ subject.javascript.run( 'window.open()' )
243
+ end
244
+ end
245
+
246
+ it 'respawns PhantomJS' do
247
+ watir = subject.watir
248
+ pid = subject.pid
249
+
250
+ expect(subject.watir.windows.size).to be > 5
251
+ @cluster.explore( page ) {}
252
+ @cluster.wait
253
+
254
+ expect(watir).not_to eq(subject.watir)
255
+ expect(pid).not_to eq(subject.pid)
256
+ expect(subject.watir.windows.size).to eq(2)
257
+ end
258
+
259
+ it 'clears the cached HTTP responses' do
260
+ subject.preload page
261
+ expect(subject.preloads).to be_any
262
+ subject.instance_variable_get(:@window_responses)
263
+
264
+ expect(subject.watir.windows.size).to be > 5
265
+ @cluster.queue( custom_job ) {}
266
+ @cluster.wait
267
+
268
+ expect(subject.instance_variable_get(:@window_responses)).to be_empty
269
+ end
264
270
  end
265
271
 
266
272
  context 'when #time_to_live reaches 0' do
@@ -278,15 +284,15 @@ describe Arachni::BrowserCluster::Worker do
278
284
  @cluster.queue( custom_job ) {}
279
285
  @cluster.wait
280
286
 
281
- watir.should_not == subject.watir
282
- pid.should_not == subject.pid
287
+ expect(watir).not_to eq(subject.watir)
288
+ expect(pid).not_to eq(subject.pid)
283
289
  end
284
290
  end
285
291
 
286
292
  context 'when cookie clearing raises' do
287
293
  context Selenium::WebDriver::Error::NoSuchWindowError do
288
294
  it 'respawns' do
289
- subject.watir.stub(:cookies) do
295
+ allow(subject.watir).to receive(:cookies) do
290
296
  raise Selenium::WebDriver::Error::NoSuchWindowError
291
297
  end
292
298
 
@@ -295,18 +301,29 @@ describe Arachni::BrowserCluster::Worker do
295
301
 
296
302
  subject.run_job( custom_job )
297
303
 
298
- watir.should_not == subject.watir
299
- pid.should_not == subject.pid
304
+ expect(watir).not_to eq(subject.watir)
305
+ expect(pid).not_to eq(subject.pid)
300
306
  end
301
307
  end
302
308
  end
303
309
  end
304
310
 
305
311
  context 'when the job takes more than #job_timeout' do
306
- it 'aborts it' do
312
+ before do
307
313
  subject.job_timeout = 1
314
+ end
315
+
316
+ it 'sets Job#time' do
317
+ @cluster.queue( sleep_job ) {}
318
+ @cluster.wait
319
+ expect(sleep_job.time).to be > 1
320
+ expect(sleep_job.time).to be < 1.1
321
+ end
322
+
323
+ it 'sets Job#timed_out?' do
308
324
  @cluster.queue( sleep_job ) {}
309
325
  @cluster.wait
326
+ expect(sleep_job).to be_timed_out
310
327
  end
311
328
  end
312
329
  end