tap-mechanize 0.5.0
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.
- 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
|
+
|