mojolicious / mojo

:sparkles: Mojolicious - Perl real-time web framework
https://mojolicious.org
Artistic License 2.0
2.66k stars 576 forks source link

Feature Request : Adding method submit_form to mojo::useragent #1382

Closed b03cmans closed 3 years ago

b03cmans commented 5 years ago

Feature Request : Adding method submit_form to Mojo::UserAgent

like this method on https://metacpan.org/pod/WWW::Mechanize#$mech-%3Esubmit_form(-...-) on WWW::Mechanize

which let you select a form from the previously fetched page, fill in its fields, and submit it. It combines the form_number/form_name/form_id, set_fields/with_fields and click methods into one higher level call .

kraih commented 5 years ago

Unfortunately that can't work, since Mojo::UserAgent does not contain request state. Only the returned transaction object does.

b03cmans commented 5 years ago

I see , is it possible to add such method to Mojo::Message::Response (or better to Mojo::DOM) to parse the result and return a new request object which can be again used by Mojo::UserAgent ?

kraih commented 5 years ago

Yes, that's more possible. On the Mojo::DOM layer you would teach Mojo::DOM::val to extract full forms (or add a new related method). And then probably add a method to Mojo::Transaction::HTTP that uses it to create a followup transaction.

kraih commented 5 years ago

We've been trying to do the Mojo::DOM part in the past, but never found a good enough solution.

Tekki commented 5 years ago

Would be great if we could replace LWP::UserAgent + HTML::Form with this.

Tekki commented 5 years ago

@b03cmans + @kiwiroy, what do you think of that?

$dom->form('#form1')->val(%newvalues)->submit($ua, '#button1');

or

$form = FormClass->new($dom->at('#form1'))->val(%newvalues);
$ua->build_tx($form->submit('#button1'));
b03cmans commented 5 years ago

@Tekki

both looks good , supposing FormClass is repesenting the HTML Form elements something like HTML::Form ,it will be very nice .

kiwiroy commented 5 years ago

I'd imagined

# Mojo::DOM::HTML::decode_form
$ua->build_tx(decode_form $dom->at('form'), $newvalues, '#button1');
Tekki commented 5 years ago

The closer I look at it the more complicated it gets. First I wanted to propose an independent module. But this will not work. Just an example: We can't create the parameters for build_tx from a DOM because it doesn't contain the request URL. If we have a FormClass module it should be built like this:

$form = $ua->get($url)->result->form('#form1');

Similar to ->result->json. As it was mentioned at the beginning of this discussion (and we probably didn't notice), FormClass should contain the DOM plus transaction information.

kraih commented 5 years ago

I mentioned it on IRC before, but i guess it's worth mentioning here too. Mojo::DOM::val once had form support, but we were not happy enough with it and so it got removed again https://github.com/mojolicious/mojo/commit/861193d93e4d83b624a91c87987254f5aeda3a6e.

Perhaps this feature should exist as two methods, Mojo::DOM::val to extract the form values, and a separate new function to get the method and URL of a form.

my $form = $dom->at('form');
my ($method, $url) = $form->target;
my $pairs = $form->val('#submit-button');

Of course you need context to create a transaction from that, but that could happen on a layer that has all that information.

my $form_tx = $ua->get('http://127.0.0.1:3000/form');
my $followup_tx = $tx->submit('#submit-button');
my $final_tx = $ua->start($followup_tx);

Just thinking out loud. 😁

kraih commented 5 years ago

I think with #1387 @kiwiroy might have proven that this feature is too big for core Mojolicious. It should probably be a separate CPAN module, maybe one or more roles.

Tekki commented 5 years ago

@kiwiroy you already started to work at such a module?

kiwiroy commented 5 years ago

@Tekki mostly translated over, will upload to CPAN later.

Tekki commented 5 years ago

@kiwiroy Is there a public repo for this code?

kiwiroy commented 5 years ago

@Tekki should all be public now.

kiwiroy commented 5 years ago

See Mojo::Transaction::HTTP::Role::Mechanize for the released role on CPAN.

stale[bot] commented 3 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

kraih commented 3 years ago

Too big for core Mojolicious and already a CPAN module.