tap-mechanize 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,11 @@
1
+ <p>Captures:</p>
2
+ <ul>
3
+ <% if captures.empty? %>
4
+ <li>(none)</li>
5
+ <% end %>
6
+ <% captures.each do |capture| %>
7
+ <li><a href="<%= uri("show/#{capture}") %>"><%= capture %></a> (<a href="<%= uri("destroy/#{capture}") %>">x</a>)</li>
8
+ <% end %>
9
+ </ul>
10
+
11
+ <p>See the <a href="<%= uri(:tutorial) %>">Tutorial</a> for help.</p>
@@ -0,0 +1,28 @@
1
+ div#<%= prefix %> {
2
+ position:relative;
3
+ top:0;
4
+ left:0;
5
+ background-color:#EFE3BC;
6
+ border: thin solid white;
7
+ font-family: arial;
8
+ font-size: 16px;
9
+ padding:0.3em;
10
+ }
11
+
12
+ span#<%= prefix %>message {
13
+ font-weight:bold;
14
+ }
15
+
16
+ a#<%= prefix %>revert {
17
+ position:absolute;
18
+ top:0.3em;
19
+ right:0.3em;
20
+ font-size:0.8em;
21
+ font-weight:normal;
22
+ text-decoration:none;
23
+ }
24
+
25
+ /* form and link notifications */
26
+ input[type=submit] {
27
+ border: medium solid #EFE3BC;
28
+ }
@@ -0,0 +1,184 @@
1
+ var RedirectHttp = {
2
+ submit_request: false,
3
+ keep_content: false,
4
+ name: 'request',
5
+
6
+ /* Returns the target uri for redirection */
7
+ redirect_uri: function() {
8
+ return '<%= redirect_action %>/' + escape(RedirectHttp.name) + "/" + RedirectHttp.keep_content;
9
+ },
10
+
11
+ /* Redirects forms and then submits the form if submit is true. */
12
+ redirect_form: function(form, submit) {
13
+ if(typeof submit == 'undefined') { submit = true };
14
+
15
+ if(submit) {
16
+
17
+ // form.submit() raises an error if an input is named submit
18
+ // (note you're hosed if the input is not type=submit)
19
+ var submit_inputs = [];
20
+ var inputs = document.getElementsByTagName('input');
21
+ for(i=0; i<inputs.length; i++) {
22
+ var input = inputs[i];
23
+ if(input.getAttribute('type') == 'submit' && input.getAttribute('name') == 'submit') {
24
+ input.setAttribute('name', '<%= prefix %>submit');
25
+ submit_inputs.push(input);
26
+ }
27
+ }
28
+
29
+ // this works without recursing to redirect_form because the onsubmit
30
+ // event handler is not executed when a form is submitted by Javascript
31
+ form.setAttribute('action', RedirectHttp.redirect_uri());
32
+ form.submit();
33
+
34
+ if(RedirectHttp.submit_request) {
35
+ this.revert();
36
+ form.submit();
37
+ };
38
+
39
+ // reset the submit inputs
40
+ for(i=0; i<submit_inputs.length; i++) {
41
+ var input = submit_inputs[i];
42
+ input.setAttribute('name', 'submit');
43
+ }
44
+ };
45
+ },
46
+
47
+ /* Redirects links and then submits the link if submit is true. */
48
+ redirect_link: function(link, submit) {
49
+ if(typeof submit == 'undefined') { submit = true };
50
+
51
+ if(submit) {
52
+ var original_href = link.getAttribute('<%= prefix %>original_href');
53
+ location.href = RedirectHttp.redirect_uri() + '?<%= redirect_parameter %>=' + escape(original_href);
54
+
55
+ if(RedirectHttp.submit_request) {
56
+ this.revert();
57
+ location.href = link.getAttribute("href");
58
+ };
59
+ };
60
+ },
61
+
62
+ /* Wraps the current onX event so that it may be called without interfering
63
+ * with the redirection (ie wrapper). */
64
+ wrap: function(current, wrapper) {
65
+ return "try {" +
66
+ " var <%= prefix %>result = function(<%= prefix %>this) { " +
67
+ current.replace(/(\W)this(?=\W)/g, "$1<%= prefix %>this") +
68
+ " }(this);" +
69
+ " RedirectHttp." + wrapper + "(this, <%= prefix %>result);" +
70
+ "} catch(ex) {" +
71
+ "alert('Error during redirection: ' + ex.message + '\\nOriginal onsubmit: " + current.replace(/'/g, "\\'") + "');" +
72
+ "}; return false;"
73
+ },
74
+
75
+ /* Redirects forms and links to '<%= redirect_action %>' */
76
+ redirect: function() {
77
+ try {
78
+
79
+ // redirect forms to the redirect_action
80
+ var forms = document.getElementsByTagName('form');
81
+ for(i=0; i<forms.length; i++) {
82
+ var form = forms[i];
83
+
84
+ // do not redirect forms related to <%= prefix %>
85
+ if(form.getAttribute("class") != "<%= prefix %>form") {
86
+
87
+ // store the original action
88
+ var input = document.createElement("input");
89
+ input.setAttribute("id", '<%= redirect_parameter %>_' + i);
90
+ input.setAttribute("name", '<%= redirect_parameter %>');
91
+ input.setAttribute("type", 'hidden');
92
+ input.setAttribute("value", form.getAttribute('action'));
93
+
94
+ form.setAttribute('<%= prefix %>index', i);
95
+ form.appendChild(input);
96
+
97
+ // redirect onSubmit
98
+ var current_on_submit = '';
99
+ if(form.hasAttribute("onSubmit")) current_on_submit = form.getAttribute("onSubmit");
100
+ var on_submit = RedirectHttp.wrap(current_on_submit, 'redirect_form');
101
+
102
+ form.setAttribute("onSubmit", on_submit);
103
+ form.setAttribute("<%= prefix %>original_callback", current_on_submit);
104
+ }
105
+ }
106
+
107
+ // redirect links to the redirect_action
108
+ var links = document.getElementsByTagName('a');
109
+ for(i=0; i<links.length; i++) {
110
+ var link = links[i];
111
+
112
+ // do not redirect links related to <%= prefix %>
113
+ if(link.getAttribute("class") != "<%= prefix %>link") {
114
+
115
+ // store the original href
116
+ link.setAttribute("<%= prefix %>original_href", link.getAttribute("href"));
117
+
118
+ // redirect onClick
119
+ var current_on_click = '';
120
+ if(link.hasAttribute("onClick")) current_on_click = link.getAttribute("onClick");
121
+ var on_click = RedirectHttp.wrap(current_on_click, 'redirect_link');
122
+
123
+ link.setAttribute("onClick", on_click);
124
+ link.setAttribute("<%= prefix %>original_callback", current_on_click);
125
+ };
126
+ }
127
+
128
+ } catch(ex) {
129
+ alert_error(ex);
130
+ }
131
+ },
132
+
133
+ /* Reverts redirection and removes the redirection div */
134
+ revert: function() {
135
+ try {
136
+
137
+ // redirect forms back to original actions
138
+ var forms = document.getElementsByTagName('form');
139
+ for(i=0; i<forms.length; i++) {
140
+ var form = forms[i];
141
+
142
+ // check in case the form was not redirected
143
+ if(form.hasAttribute('<%= prefix %>index')) {
144
+ var index = form.getAttribute('<%= prefix %>index');
145
+ var input = document.getElementById("<%= redirect_parameter %>_" + index);
146
+
147
+ form.setAttribute('action', input.value);
148
+ form.removeAttribute('<%= prefix %>index');
149
+ form.removeChild(input);
150
+
151
+ form.setAttribute('onSubmit', form.getAttribute('<%= prefix %>original_callback'));
152
+ form.removeAttribute('<%= prefix %>original_callback');
153
+ }
154
+ }
155
+
156
+ // redirect links back to original hrefs
157
+ var links = document.getElementsByTagName('a');
158
+ for(i=0; i<links.length; i++) {
159
+ var link = links[i];
160
+
161
+ // check in case the link was not redirected
162
+ if(link.hasAttribute('<%= prefix %>original_href')) {
163
+ link.setAttribute('href', link.getAttribute('<%= prefix %>original_href'));
164
+ link.removeAttribute('<%= prefix %>original_href');
165
+
166
+ link.setAttribute('onClick', link.getAttribute('<%= prefix %>original_callback'));
167
+ link.removeAttribute('<%= prefix %>original_callback');
168
+ }
169
+ }
170
+
171
+ } catch(ex) {
172
+ alert_error(ex);
173
+ }
174
+
175
+ // remove self
176
+ var redirect_http = document.getElementById("<%= prefix %>")
177
+ if(redirect_http) document.body.removeChild(redirect_http);
178
+ },
179
+
180
+ // Alerts of errors due to RedirectHttp
181
+ alert_error: function(ex) {
182
+ alert("Redirect HTTP Error: " + ex.message + "\n\n The webpage may have been corrupted; be sure to refresh.");
183
+ }
184
+ };
@@ -0,0 +1,15 @@
1
+ <span id='<%= prefix %>message'>Redirecting HTTP Requests</span>
2
+ <ul id='<%= prefix %>controls' >
3
+ <li><input id='<%= prefix %>name' type='text' value='' onchange='javascript:RedirectHttp.name=this.value;'>name</input></li>
4
+ <li><input id='<%= prefix %>submit_request' type='checkbox' onchange='javascript:RedirectHttp.submit_request=this.checked;'>submit after capture</input></li>
5
+ <li><input id='<%= prefix %>keep_content' type='checkbox' onchange='javascript:RedirectHttp.keep_content=this.checked;'>capture uploaded data</input></li>
6
+ </ul>
7
+ <a id='<%= prefix %>revert' href='javascript:RedirectHttp.revert();' class="<%= prefix %>link">close</a>
8
+
9
+ <style type="text/css">
10
+ <%= css %>
11
+ </style>
12
+
13
+ <script type="text/javascript">
14
+ <%= script %>
15
+ </script>
@@ -0,0 +1,108 @@
1
+ <h1>Redirection Tests</h1>
2
+
3
+ <p>
4
+ Redirection occurs onSubmit for forms, and onClick for links. The redirection
5
+ wraps the current hook, if it exists, and ensures that it executes properly.
6
+ References to 'this' and return statements should be handled properly, but
7
+ naturally it's hard to handle all cases.
8
+ </p>
9
+
10
+ <p>
11
+ Run tests by redirecting, then submitting the forms to see if the correct
12
+ actions occur.
13
+ </p>
14
+
15
+ <%
16
+ def assert(message, *javascripts)
17
+ assert_literal message, *javascripts.collect {|js| "'#{js}'"}
18
+ end
19
+ def assert_literal(message, *javascripts)
20
+ rows = javascripts.collect do |javascript|
21
+ %Q{<tr>
22
+ <td><a href='/capture/say?words=link+was+clicked' onclick=#{javascript.gsub(/action/, "href")}>#{javascript[1...-1]}</a></td>
23
+ <td>
24
+ <form action='/capture/say' onsubmit=#{javascript}>
25
+ <input name='words' value="form was submitted"/>
26
+ <input type="submit" value="submit" />
27
+ </form>
28
+ </td>
29
+ </tr>
30
+ } end
31
+ %Q{<h3>#{message}</h3>
32
+ <table>
33
+ #{rows.join("\n")}
34
+ </table>
35
+ }
36
+ end
37
+ %>
38
+
39
+ <script>
40
+ function submit_form(form) {
41
+ alert(form.action || form.href);
42
+ return true;
43
+ };
44
+ function thisthisthis_with_this(form) {
45
+ alert(form.action || form.href);
46
+ return true;
47
+ };
48
+ </script>
49
+ <%= assert("Alerts form action then redirects",
50
+ "alert(this.action);",
51
+ "javascript:alert(this.action);",
52
+ "this;alert(this.action);this;",
53
+ "alert(this.action); return true;",
54
+ "submit_form(this);",
55
+ "submit_form(this); return true;",
56
+ "return submit_form(this);",
57
+ "return thisthisthis_with_this(this);"
58
+ )%>
59
+
60
+ <%= assert_literal("Alerts form action then redirects",
61
+ "\"alert('hello');\"",
62
+ "'alert(\"hello\");'"
63
+ )%>
64
+
65
+
66
+ <script>
67
+ function do_not_submit_form(form) {
68
+ alert(form.action || form.href);
69
+ return false;
70
+ };
71
+ </script>
72
+ <%= assert("Alerts form action and does not redirect",
73
+ "alert(this.action); return false;",
74
+ "do_not_submit_form(this); return false;",
75
+ "return do_not_submit_form(this);"
76
+ )%>
77
+
78
+ <script>
79
+ function throw_error(form) {
80
+ throw "Error!"
81
+ };
82
+ </script>
83
+ <%= assert("Alerts error and does not redirect",
84
+ "throw \"Error!\"",
85
+ "throw_error(this); return true;"
86
+ )%>
87
+
88
+ <h3>Check when an input is named submit...</h3>
89
+ <p>Which can cause the error: <a href="http://www.spiration.co.uk/post/1232/Submit%20is%20not%20a%20function">(Submit is not a function)</a></p>
90
+ <form action='/capture/say'>
91
+ <input name='words' value="button named submit"/>
92
+ <input type="submit" name="submit" value="submit" />
93
+ </form>
94
+
95
+ <p>Now check for multiple submit buttons</p>
96
+ <form action='/capture/say'>
97
+ <input name='words' value="button named submit"/>
98
+ <input type="submit" name="submit" value="submit" />
99
+ <input type="submit" name="submit" value="submit" />
100
+ <input type="submit" name="submit" value="submit" />
101
+ </form>
102
+
103
+ <p>When a non-submit input is named submit, you're hosed. This should raise an error:</p>
104
+ <form action='/capture/say'>
105
+ <input name="submit" type="hidden"/>
106
+ <input name="words" value="input named submit"/>
107
+ <input type="submit" value="submit" />
108
+ </form>
@@ -0,0 +1,57 @@
1
+ <p>
2
+ This is a tutorial for capturing http requests for modification and/or
3
+ resubmission at a later date. First, get the environment right:
4
+ </p>
5
+
6
+ <ul>
7
+ <li>Be sure you're viewing this in <a href="http://www.mozilla.com/en-US/firefox/">Firefox</a></li>
8
+ <li>Install <a href="http://labs.mozilla.com/2008/08/introducing-ubiquity/">Ubiquity</a></li>
9
+ <li>Subscribe to the redirect-http command on this page</li>
10
+ </ul>
11
+
12
+ <p>
13
+ Now capture the request from this page (use the same procedure wherever
14
+ else you need to capture the parameters of a form):
15
+ </p>
16
+
17
+ <ul>
18
+ <li>Bring up Ubiquity in Firefox by pressing 'option+space'</li>
19
+ <li>Enter the command: redirect_http</li>
20
+ </ul>
21
+
22
+ <p>
23
+ You should now see some notification that you're redirecting this page.
24
+ Write what you want to say, hit submit, and you'll be asked to save a
25
+ configuration file for the request. Save it, then on the command line
26
+ execute this:
27
+ </p>
28
+
29
+ <pre><code> % tap run -- load/yaml --:s submit --: dump &lt; request.yml</code></pre>
30
+
31
+ <p>
32
+ The request will be submitted and you'll get a printout of the response
33
+ body. To prove everything worked right, click the close link in the
34
+ redirection bar and resubmit the form.
35
+ </p>
36
+
37
+ <a href="/capture/say?words=link+was+clicked">Link</a>
38
+ <form action='/capture/say'>
39
+ Form: <input name='words' value="form was submitted"/>
40
+ <input type="submit" value="submit" />
41
+ </form>
42
+
43
+ <p>
44
+ Redirection occurs via the on-click and on-submit callbacks for links and
45
+ forms, respectively. The existing behavior is preserved, as can be
46
+ demonstrated below:
47
+ </p>
48
+
49
+ <pre>
50
+ &lt;form action='/capture/say' onsubmit='alert("Form was submitted!")'>
51
+ </pre>
52
+
53
+ <a href="/capture/say?words=link+was+clicked" onclick='alert("Link was clicked!")'>Link with OnClick</a>
54
+ <form action='/capture/say' onsubmit='alert("Form was submitted!")'>
55
+ Form with OnSubmit: <input name='words' value="form was submitted"/>
56
+ <input type="submit" value="submit" />
57
+ </form>
metadata ADDED
@@ -0,0 +1,108 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tap-mechanize
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.5.0
5
+ platform: ruby
6
+ authors:
7
+ - Simon Chiang
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-03-23 00:00:00 -06:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: tap-ubiquity
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - "="
22
+ - !ruby/object:Gem::Version
23
+ version: 0.2.0
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: tap-tasks
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.1.0
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: mechanize
37
+ type: :runtime
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: 0.9.2
44
+ version:
45
+ description:
46
+ email: simon.a.chiang@gmail.com
47
+ executables: []
48
+
49
+ extensions: []
50
+
51
+ extra_rdoc_files:
52
+ - README
53
+ - MIT-LICENSE
54
+ - History
55
+ files:
56
+ - lib/tap/mechanize/agent.rb
57
+ - lib/tap/mechanize/capture.rb
58
+ - lib/tap/mechanize/get.rb
59
+ - lib/tap/mechanize/request.rb
60
+ - lib/tap/mechanize/submit.rb
61
+ - lib/tap/mechanize/utils.rb
62
+ - lib/tap/mechanize/test.rb
63
+ - lib/tap/mechanize/test/echo_server.rb
64
+ - lib/tap/mechanize/test/mock_server.rb
65
+ - tap.yml
66
+ - views/tap/mechanize/capture/http.erb
67
+ - views/tap/mechanize/capture/index.erb
68
+ - views/tap/mechanize/capture/redirect.css
69
+ - views/tap/mechanize/capture/redirect.js
70
+ - views/tap/mechanize/capture/redirect_http.erb
71
+ - views/tap/mechanize/capture/test.erb
72
+ - views/tap/mechanize/capture/tutorial.erb
73
+ - README
74
+ - MIT-LICENSE
75
+ - History
76
+ has_rdoc: true
77
+ homepage: http://tap.rubyforge.org/tap-mechanize
78
+ post_install_message:
79
+ rdoc_options:
80
+ - --main
81
+ - README
82
+ - -S
83
+ - -N
84
+ - --title
85
+ - Tap Mechanize
86
+ require_paths:
87
+ - lib
88
+ required_ruby_version: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: "0"
93
+ version:
94
+ required_rubygems_version: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ version: "0"
99
+ version:
100
+ requirements: []
101
+
102
+ rubyforge_project: tap
103
+ rubygems_version: 1.3.1
104
+ signing_key:
105
+ specification_version: 2
106
+ summary: A task library for submitting http requests using Tap.
107
+ test_files: []
108
+