tap-mechanize 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History +41 -0
- data/MIT-LICENSE +19 -0
- data/README +58 -0
- data/lib/tap/mechanize/agent.rb +101 -0
- data/lib/tap/mechanize/capture.rb +194 -0
- data/lib/tap/mechanize/get.rb +20 -0
- data/lib/tap/mechanize/request.rb +33 -0
- data/lib/tap/mechanize/submit.rb +30 -0
- data/lib/tap/mechanize/test.rb +59 -0
- data/lib/tap/mechanize/test/echo_server.rb +20 -0
- data/lib/tap/mechanize/test/mock_server.rb +31 -0
- data/lib/tap/mechanize/utils.rb +296 -0
- data/tap.yml +1 -0
- data/views/tap/mechanize/capture/http.erb +31 -0
- data/views/tap/mechanize/capture/index.erb +11 -0
- data/views/tap/mechanize/capture/redirect.css +28 -0
- data/views/tap/mechanize/capture/redirect.js +184 -0
- data/views/tap/mechanize/capture/redirect_http.erb +15 -0
- data/views/tap/mechanize/capture/test.erb +108 -0
- data/views/tap/mechanize/capture/tutorial.erb +57 -0
- metadata +108 -0
@@ -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 < 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
|
+
<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
|
+
|