#!/usr/bin/perl -T
=> 116
+ 24
+ 2
+ 3
+ 4;
BEGIN{ use_ok
'HTML::DOM'
};
{
my
$req
;
sub
new_doc {
0&
&$req
;
my
$doc
= new HTML::DOM
url
=>
shift
;
$doc
->default_event_handler(
sub
{
my
$target
=
shift
->target;
$req
= (
$target
->tag eq
'form'
?
$target
:
$target
->form)->make_request;
});
$doc
}
sub
click {
shift
->click;
return
$req
;
}
}
my
@warn
;
$SIG
{__WARN__} =
sub
{
push
(
@warn
,
$_
[0]) };
<form action="abc" name="foo">
<input name="name">
</form>
<form></form>
EOT
$doc
->
close
;
my
$f
= (
$doc
->forms)[0];
is(
$f
->value(
"name"
),
""
);
my
$req
=
$f
->main::click;
is(
$req
->method,
"GET"
);
$f
->value(
name
=>
"Gisle Aas"
);
$req
=
$f
->main::click;
is(
$req
->method,
"GET"
);
is(
$f
->attr(
"name"
),
"foo"
);
is(
$f
->attr(
"method"
),
undef
);
$f
= (
$doc
->forms)[1];
is(
$f
->method,
"get"
);
is(
$f
->enctype,
"application/x-www-form-urlencoded"
);
$doc
->
write
(
<<'EOT'); $doc->close; $f = ($doc->forms)[0];
<form method=post>
<input name=i type="image" src="foo.gif">
<input name=c type="checkbox" checked>
<input name=r type="radio" value="a">
<input name=r type="radio" value="b" checked>
<input name=t type="text">
<input name=p type="PASSWORD">
<input name=h type="hidden" value=xyzzy>
<input name=s type="submit" value="Doit!">
<input name=r type="reset">
<input name=b type="button">
<input name=f type="file" value="foo.txt">
<input name=x type="xyzzy">
<textarea name=a>
abc
</textarea>
<select name=s>
<option>Foo
<option value="bar" selected>Bar
</select>
<select name=m multiple>
<option selected value="a">Foo
<option selected value="b">Bar
</select>
</form>
EOT
my
$t
=
<<'EOT';
Content-Length: 76
Content-Type: application/x-www-form-urlencoded; charset="utf-8"
i.x=1&i.y=1&c=on&r=b&t=&p=&h=xyzzy&f=foo.txt&x=&a=%0Aabc%0A+++&s=bar&m=a&m=b
EOT
(
$t
=
quotemeta
$t
) =~ s/\\%0A/(?:%0D)?%0A/g;
$t
=~ s/76/(?:76|82)/;
like(
$f
->main::click->as_string,
qr/^$t\z/
);
$doc
->
write
(
<<'EOT'); $doc->close; $f = ($doc->forms)[0];
<form>
<input type=submit value="Upload it!" name=n disabled>
<input type=image alt="Foo">
<input type=text name=t value="1">
</form>
EOT
is(
$f
->main::click->as_string,
<<'EOT');
EOT
$doc
->
write
(
<<'EOT'); $doc->close; $f = ($doc->forms)[0];
<form method=post enctype="MULTIPART/FORM-DATA">
<input name=f type=file value=>
<input type=submit value="Upload it!">
</form>
EOT
is(
$f
->main::click->as_string,
<<'EOT');
Content-Length: 0
Content-Type: multipart/form-data; boundary=none
EOT
my
$filename
=
sprintf
"foo-%08d.txt"
, $$;
die
if
-e
$filename
;
open
(FILE,
">$filename"
) ||
die
;
binmode
(FILE);
print
FILE
"This is some text\n"
;
close
(FILE) ||
die
;
$f
->value(
f
=>
$filename
);
is(
$f
->main::click->as_string,
<<"EOT");
Content-Length: 139
Content-Type: multipart/form-data; boundary=xYzZY
--xYzZY\r
Content-Disposition: form-data; name="f"; filename="$filename"\r
Content-Type: text/plain\r
\r
This is some text
\r
--xYzZY--\r
EOT
unlink
(
$filename
) ||
warn
"Can't unlink '$filename': $!"
;
is(
@warn
, 0);
$doc
->
write
(
<<'EOT'); $doc->close; $f = ($doc->forms)[0];
<form>
<input type=checkbox name=x> I like it!
</form>
EOT
SKIP:{ skip
'not supported'
, 1;
$f
->find_input(
"x"
)->check;
is(
$f
->main::click->as_string,
<<"EOT");
EOT
}
SKIP: { skip
'not yet implemented'
, 3;
$f
->value(
"x"
,
"off"
);
ok(
$f
->main::click->as_string,
<<"EOT");
EOT
$f
->value(
"x"
,
"I like it!"
);
ok(
$f
->main::click->as_string,
<<"EOT");
EOT
$f
->value(
"x"
,
"I LIKE IT!"
);
ok(
$f
->main::click->as_string,
<<"EOT");
EOT
}
$doc
->
write
(
<<'EOT'); $doc->close; $f = ($doc->forms)[0];
<form>
<select name=x>
<option value=1>one
<option value=2>two
<option>3
</select>
<select name=y multiple>
<option value=1>
</select>
</form>
EOT
$f
->value(
"x"
,
"one"
);
is(
$f
->main::click->as_string,
<<"EOT");
EOT
SKIP: { skip
'not yet implemented'
, 2;
$f
->value(
"x"
,
"TWO"
);
ok(
$f
->main::click->as_string,
<<"EOT");
EOT
ok(
join
(
":"
,
$f
->find_input(
"x"
)->value_names),
"one:two:3"
);
}
is(
join
(
":"
,
map
$_
->name,
$f
->find_input(
undef
,
"option"
)),
"x:y"
);
$doc
->
write
(
<<'EOT'); $doc->close; $f = ($doc->forms)[0];
<form>
<input name=x value=1 disabled>
<input name=y value=2 READONLY type=TEXT>
<input name=z value=3 type=hidden>
</form>
EOT
is(
$f
->value(
"x"
), 1);
is(
$f
->value(
"y"
), 2);
is(
$f
->value(
"z"
), 3);
is(
$f
->main::click->uri->query,
"y=2&z=3"
);
my
$input
=
$f
->find_input(
"x"
);
is(
$input
->type,
"text"
);
SKIP: { skip
'not supported'
, 1;
ok(!
$input
->readonly);
}
ok(
$input
->disabled);
ok(
$input
->disabled(0));
ok(!
$input
->disabled);
is(
$f
->main::click->uri->query,
"x=1&y=2&z=3"
);
$input
=
$f
->find_input(
"y"
);
is(
$input
->type,
"text"
);
SKIP: { skip
'not supported'
, 1;
ok(
$input
->readonly);
}
ok(!
$input
->disabled);
$input
->value(22);
is(
$f
->main::click->uri->query,
"x=1&y=22&z=3"
);
SKIP:{ skip
'not yet implemented'
, 2;
ok(
@warn
, 1);
ok(
$warn
[0] =~ /^Input
'y'
is readonly/);
}
@warn
= ();
SKIP:{ skip
'not supported'
, 2;
ok(
$input
->readonly(0));
ok(!
$input
->readonly);
}
$input
->value(222);
SKIP: { skip
'not yet implemented'
, 1;
ok(
@warn
, 0);
print
@warn
;
}
is(
$f
->main::click->uri->query,
"x=1&y=222&z=3"
);
$input
=
$f
->find_input(
"z"
);
is(
$input
->type,
"hidden"
);
SKIP: { skip
'not supported'
, 1;
ok(
$input
->readonly);
}
ok(!
$input
->disabled);
$doc
->
write
(
<<'EOT'); $doc->close; $f = ($doc->forms)[0];
<form>
<textarea name="t" type="hidden">
<foo>
</textarea>
<select name=s value=s>
<option name=y>Foo
<option name=x value=bar type=x>Bar
</form>
EOT
is(
$f
->value(
"t"
),
"\n<foo>\n"
);
SKIP: { skip
'doesn\'t work yet'
, 2; is(
$f
->value(
"s"
),
"Foo"
);
is(
join
(
":"
,
$f
->find_input(
"s"
)->possible_values),
"Foo:bar"
); }
SKIP: { skip
'not supported'
, 1;
ok(
join
(
":"
,
$f
->find_input(
"s"
)->other_possible_values),
"bar"
);
}
SKIP: { skip
"doesn't work yet"
,2; is(
$f
->value(
"s"
,
"bar"
),
"Foo"
);
is(
$f
->value(
"s"
),
"bar"
);}
SKIP: { skip
'not supported'
, 1;
ok(
join
(
":"
,
$f
->find_input(
"s"
)->other_possible_values),
""
);
}
$doc
->
write
(
<<'EOT'); $doc->close; $f = ($doc->forms)[0];
<form>
<input type=radio name=r0 value=1 disabled>one
<input type=radio name=r1 value=1 disabled>one
<input type=radio name=r1 value=2>two
<input type=radio name=r1 value=3>three
<input type=radio name=r2 value=1>one
<input type=radio name=r2 value=2 disabled>two
<input type=radio name=r2 value=3>three
<select name=s0>
<option disabled>1
</select>
<select name=s1>
<option disabled>1
<option>2
<option>3
</select>
<select name=s2>
<option>1
<option disabled>2
<option>3
</select>
<select name=s3 disabled>
<option>1
<option disabled>2
<option>3
</select>
<select name=m0 multiple>
<option disabled>1
</select>
<select name=m1 multiple="">
<option disabled>1
<option>2
<option>3
</select>
<select name=m2 multiple>
<option>1
<option disabled>2
<option>3
</select>
<select name=m3 disabled multiple>
<option>1
<option disabled>2
<option>3
</select>
</form>
EOT
ok(
$f
->find_input(
"r0"
)->disabled);
ok(!
eval
{
$f
->value(
"r0"
, 1);});
ok($@ && $@ =~ /^The value
'1'
has
been disabled
for
field
'r0'
/);
SKIP: { skip
'not supported'
, 4;
ok(
$f
->find_input(
"r0"
)->disabled(0));
ok(!
$f
->find_input(
"r0"
)->disabled);
is(
$f
->value(
"r0"
, 1),
undef
);
is(
$f
->value(
"r0"
), 1);
}
ok(!
$f
->find_input(
"r1"
)->disabled);
is(
$f
->value(
"r1"
, 2),
undef
);
is(
$f
->value(
"r1"
), 2);
ok(!
eval
{
$f
->value(
"r1"
, 1);});
ok($@ && $@ =~ /^The value
'1'
has
been disabled
for
field
'r1'
/);
is(
$f
->value(
"r2"
, 1),
undef
);
ok(!
eval
{
$f
->value(
"r2"
, 2);});
ok($@ && $@ =~ /^The value
'2'
has
been disabled
for
field
'r2'
/);
SKIP: { skip
'not yet implemented'
, 2;
ok(!
eval
{
$f
->value(
"r2"
,
"two"
);});
ok($@ && $@ =~ /^The value
'two'
has
been disabled
for
field
'r2'
/);
}
SKIP : { skip
'not supported'
, 4;
ok(!
$f
->find_input(
"r2"
)->disabled(1));
ok(!
eval
{
$f
->value(
"r2"
, 1);});
ok($@ && $@ =~ /^The value
'1'
has
been disabled
for
field
'r2'
/);
ok(
$f
->find_input(
"r2"
)->disabled(0));
}
ok(!
$f
->find_input(
"r2"
)->disabled);
SKIP : { skip
'not supported'
, 1;
is(
$f
->value(
"r2"
, 2), 1);
}
ok(
$f
->find_input(
"s0"
)->disabled);
ok(!
$f
->find_input(
"s1"
)->disabled);
ok(!
$f
->find_input(
"s2"
)->disabled);
ok(
$f
->find_input(
"s3"
)->disabled);
SKIP: { skip
"doesn't work yet"
, 2;
ok(!
eval
{
$f
->value(
"s1"
, 1);});
ok($@ && $@ =~ /^The value
'1'
has
been disabled
for
field
's1'
/);
}
ok(
$f
->find_input(
"m0"
)->disabled);
SKIP: { skip
"doesn't work yet"
, 17;
ok(
$f
->find_input(
"m1"
,
undef
, 1)->disabled);
ok(!
$f
->find_input(
"m1"
,
undef
, 2)->disabled);
ok(!
$f
->find_input(
"m1"
,
undef
, 3)->disabled);
ok(!
$f
->find_input(
"m2"
,
undef
, 1)->disabled);
ok(
$f
->find_input(
"m2"
,
undef
, 2)->disabled);
ok(!
$f
->find_input(
"m2"
,
undef
, 3)->disabled);
ok(
$f
->find_input(
"m3"
,
undef
, 1)->disabled);
ok(
$f
->find_input(
"m3"
,
undef
, 2)->disabled);
ok(
$f
->find_input(
"m3"
,
undef
, 3)->disabled);
$f
->find_input(
"m3"
,
undef
, 2)->disabled(0);
ok(!
$f
->find_input(
"m3"
,
undef
, 2)->disabled);
is(
$f
->find_input(
"m3"
,
undef
, 2)->value(2),
undef
);
is(
$f
->find_input(
"m3"
,
undef
, 2)->value(
undef
), 2);
$f
->find_input(
"m3"
,
undef
, 2)->disabled(1);
ok(
$f
->find_input(
"m3"
,
undef
, 2)->disabled);
is(
eval
{
$f
->find_input(
"m3"
,
undef
, 2)->value(2)},
undef
);
ok($@ && $@ =~ /^The value
'2'
has
been disabled/);
is(
eval
{
$f
->find_input(
"m3"
,
undef
, 2)->value(
undef
)},
undef
);
ok($@ && $@ =~ /^The
'm3'
field can't be unchecked/);
}
SKIP:{ skip
'not supported'
, 5;
$doc
->
write
(
<<'EOT'); $doc->close; $f = ($doc->forms)[0];
<keygen NAME="randomkey" CHALLENGE="1234567890">
<input TYPE="text" NAME="Field1" VALUE="Default Text">
</form>
EOT
ok(
$f
->find_input(
"randomkey"
));
ok(
$f
->find_input(
"randomkey"
)->challenge,
"1234567890"
);
ok(
$f
->find_input(
"randomkey"
)->keytype,
"rsa"
);
ok(
$f
->main::click->as_string,
<<EOT);
Content-Length: 19
Content-Type: application/x-www-form-urlencoded; charset=utf-8
Field1=Default+Text
EOT
$f
->value(
randomkey
=>
"foo"
);
ok(
$f
->main::click->as_string,
<<EOT);
Content-Length: 33
Content-Type: application/x-www-form-urlencoded; charset=utf-8
randomkey=foo&Field1=Default+Text
EOT
}
$doc
->
write
(
<<'EOT'); $doc->close; $f = ($doc->forms)[0];
<select name=s>
<option>1
<option>2
<input name=t>
</form>
EOT
ok(
$f
);
ok(
$f
->find_input(
"t"
));
$doc
->
write
(
<<'EOT'); $doc->close; my @f = $doc->forms;
<select name=s>
<option>1
<option>2
</form>
<input name=t>
</form>
EOT
is(
@f
, 2);
ok(
$f
[0]->find_input(
"s"
));
ok(
$f
[1]->find_input(
"t"
));
SKIP: { skip
'not supported (?)'
, 5;
$doc
->
write
(
<<'EOT'); $doc->close; $f = ($doc->forms)[0];
<fieldset>
<legend>Radio Buttons with Labels</legend>
<label>
<input type=radio name=r0 value=0 />zero
</label>
<label>one
<input type=radio name=r1 value=1>
</label>
<label for="r2">two</label>
<input type=radio name=r2 id=r2 value=2>
<label>
<span>nested</span>
<input type=radio name=r3 value=3>
</label>
<label>
before
and <input type=radio name=r4 value=4>
after
</label>
</fieldset>
</form>
EOT
is(
join
(
":"
,
$f
->find_input(
"r0"
)->value_names),
"zero"
);
is(
join
(
":"
,
$f
->find_input(
"r1"
)->value_names),
"one"
);
is(
join
(
":"
,
$f
->find_input(
"r2"
)->value_names),
"two"
);
is(
join
(
":"
,
$f
->find_input(
"r3"
)->value_names),
"nested"
);
is(
join
(
":"
,
$f
->find_input(
"r4"
)->value_names),
"before and after"
);
}
->
write
(
<<'EOT', ); my $form = ($doc->forms)[0];
<form>
<input type="hidden" name="hidden_1">
<input type="checkbox" name="checkbox_1" value="c1_v1" CHECKED>
<input type="checkbox" name="checkbox_1" value="c1_v2" CHECKED>
<input type="checkbox" name="checkbox_2" value="c2_v1" CHECKED>
<select name="multi_select_field" multiple="1">
<option> 1
<option> 2
<option> 3
</select>
</form>
EOT
is(
$form
->param, 4);
is(j(
$form
->param),
"hidden_1:checkbox_1:checkbox_2:multi_select_field"
);
is(
$form
->param(
'hidden_1'
),
''
);
is(
$form
->param(
'checkbox_1'
),
'c1_v1'
);
is(j(
$form
->param(
'checkbox_1'
)),
'c1_v1:c1_v2'
);
is(
$form
->param(
'checkbox_2'
),
'c2_v1'
);
is(j(
$form
->param(
'checkbox_2'
)),
'c2_v1'
);
ok(!
defined
(
$form
->param(
'multi_select_field'
)));
is(j(
$form
->param(
'multi_select_field'
)),
''
);
ok(!
defined
(
$form
->param(
'unknown'
)));
is(j(
$form
->param(
'unknown'
)),
''
);
ok(!
@warn
,
'no warnings'
);
$form
->param(
'hidden_1'
,
'x'
);
SKIP:{ skip
'not yet implemented'
, 1;
ok(
@warn
&&
$warn
[0] =~ /^Input
'hidden_1'
is readonly/);
}
@warn
= ();
is(j(
$form
->param(
'hidden_1'
)),
'x'
);
eval
{
$form
->param(
'checkbox_1'
,
'foo'
);
};
ok($@);
is(j(
$form
->param(
'checkbox_1'
)),
'c1_v1:c1_v2'
);
$form
->param(
'checkbox_1'
,
'c1_v2'
);
is(j(
$form
->param(
'checkbox_1'
)),
'c1_v2'
);
$form
->param(
'checkbox_1'
,
'c1_v2'
);
is(j(
$form
->param(
'checkbox_1'
)),
'c1_v2'
);
$form
->param(
'checkbox_1'
, []);
is(j(
$form
->param(
'checkbox_1'
)),
''
);
$form
->param(
'checkbox_1'
, [
'c1_v2'
,
'c1_v1'
]);
is(j(
$form
->param(
'checkbox_1'
)),
'c1_v1:c1_v2'
);
$form
->param(
'checkbox_1'
, []);
is(j(
$form
->param(
'checkbox_1'
)),
''
);
$form
->param(
'checkbox_1'
,
'c1_v2'
,
'c1_v1'
);
is(j(
$form
->param(
'checkbox_1'
)),
'c1_v1:c1_v2'
);
SKIP: { skip
"doesn't work yet"
, 1;
$form
->param(
'multi_select_field'
, 3, 2);
is(j(
$form
->param(
'multi_select_field'
)),
"2:3"
);
}
print
"# Done\n"
;
ok(!
@warn
);
sub
j {
join
(
":"
,
@_
);
}
$doc
->
open
;
$doc
->
write
(
<input name=frat value=flin></form>'
);
is +(
$doc
->forms)[0]->make_request->uri,
'make_request with the file protocol'
;
$doc
->
open
;
$doc
->
write
(
'<form action=
"data:text/html,squext"
><input name=plew value=glor>
<input name=frat value=flin></form>'
);
is +(
$doc
->forms)[0]->make_request->uri,
'data:text/html,squext'
,
'make_request with GET method and data: URL'
;
$doc
->
close
;
$doc
->
write
("<form><button name=b value=v><button name=b value=w>
<button name=btnAccept></button>(
no
value)
<button type=
reset
name=c value=d>
<button type=button name=e value=f>
</form>");
is
$doc
->getElementsByTagName(
'button'
)->[1]->main'click->as_string,
is +(
$doc
->forms)[0]->main::click->as_string,
'form->click supports <button>s'
;
is
$doc
->getElementsByTagName(
'button'
)->[2]->main'click->as_string,
{
my
$doc
= new HTML::DOM;
$doc
->
write
('<title>What’s up, Doc?</title>
<form><
select
name=Bunny><!--
no
options --></
select
></form>');
$doc
->
close
;
is
eval
{
$doc
->forms->[0]->{Bunny}->options->name } || diag($@),
'Bunny'
,
'select->options->name no longer dies when there are no options'
;
$doc
->
write
(
'<form><input name=c type=checkbox value=12345 checked></form>'
);
my
$f
=
$doc
->forms->[0];
$f
->value(
c
=>
undef
);
ok !
$f
->{c}->checked,
'form->value(field, undef) unchecks a checkbox'
;
local
$SIG
{__WARN__};
$f
->innerHTML(
'<input name=c type=radio value=a><input name=c type=radio value=b>'
);
my
$radioset
=
$f
->find_input(
'c'
);
$radioset
->value(
'a'
);
ok
$f
->{c}[0]->checked && !
$f
->{c}[1]->checked,
'->value(x) on radio nodelist works if nothing is checked yet'
;
$radioset
->value(
'b'
);
ok !
$f
->{c}[0]->checked &&
$f
->{c}[1]->checked,
'->value(x) on radio nodelist works if something is checked already'
;
}