Wait for form response after submitting with button.click() - puppeteer

I am using Puppeteer to submit a form and I can't figure out how to wait for the response because the normal approaches don't work.
Submitting must be done by invoking click() on the submit button rather than calling form.submit() which on this webpage results in an error that I can't control. Therefore, this does not work:
await page.$eval('#form', form => form.submit);
Submitting the form does not navigate to a new page, but rather modifies the HTML in place. I have also tried waitForNavigation with every waitUntil option, none works.
Are there any other approaches I can try? Thanks

Submitting the form does not navigate to a new page, but rather modifies the HTML in place.
In this case you can wait for a css selector via page.waitForSelector
For example if a success message is shown above your form after a successful submit, just wait for this css selector to appear in the dom:
await page.waitForSelector('form div.success');

Related

How to Prevent JEditable Form Submission with Webkit browsers

Using the JEditable JQuery plugin, and everything seemed to work fine in Firefox. However, in Chrome whenever I selected something out of a JEditable dropdown, or clicked Enter when editing a JEditable textbox, the form JEditable creates on the fly was being submitted, and my entire page was refreshing. I didn't want that to happen, as I've got it configured to call a custom function that makes an Ajax call to do the update. How do you keep the JEditable form from being submitted when changing the value of one of the form inputs?
My understanding from researching online is this is a Webkit-browser issue, not just a Chrome issue, as it seems Webkit-based browsers automatically submit forms when inputs in the form are changed.
After much trial-and-error I found one way to get around this is to use JEditable's bind function. The bind function gives you access to the form JEditable creates, and you can hijack the onsubmit event with that.
So first, create a function to override the form's onsubmit event.
var bindSubmitDisableWebkitSubmission = function(settings, self){
$('form', self).attr("onsubmit", "return false;");
}
Then bind that function to the various JEditable events that you don't want to submit the form.
$.editable.types['select'].plugin = bindSubmitDisableWebkitSubmission;
Note that using preventDefault and returning false (see below) didn't work.
function bindSubmitDisableWebkitSubmission (settings, self) {
$('form', self).submit(function(e){
e.preventDefault();
return false;
});
}

Manually invoke HTML5 form validation

I have a legacy form that I'm trying to update to do simple HTML5 form validation.
Currently, it uses reCaptcha, and invokes a verify() function that validates the reCaptcha challenge before forwarding the contents of the form. I would like to ensure that the form passes HTML5 validation before continuing with the reCaptcha processing, and display the appropriate error messages that the browser would use by default.
The iframe containing the form as the <!DOCTYPE html> doctype. The input fields have the required attribute.
The submit button has the following:
<input type="button" id="script_send" onclick="javascript:verify(this.form);" value="ENVIAR">
The verify script has the basic structure.
function verify(theForm) {
form = theForm;
/* Recaptcha processing */
}
I tried using
if (!form.checkValidity()) {
return false;
}
and even though the form was not submitted, I get no errors displayed on the screen, showing the user what fields they should be providing.
I have seen this jsfiddle [http://jsfiddle.net/5ycZz/] used to demonstrate the checkValidity() function, but even that does not display the visual error cues that I would expect to see, in Chrome, IE10 or FF.
Try setting the submit event on the form instead of putting a click action on the submit button. The submit event fires AFTER validation so it should only happen if all other constraints passed. This also means you wont have to call form.checkValidity() in your verify function.
<form onsubmit="verify(this)">
...
</form>
This solving trouble:
if (!form.checkValidity()) {
form.reportValidity();
return false;
}

Mozilla Firefox form values reset on history.back

I'm writing a PHP script. I've got a form uses post method and action to another page. If an error occurs, I show a message on that target page, and let the user go back via a link that triggers history.back(); javascript function.
So user clicks that link and turns back to the page includes form and values entered by user should remain in inputs.
They stay on Chrome, but lost in Firefox. Is there a way to keep DOM information on all major browsers using history, or is the only way to do that is to use a cache like session, cookies, etc. ?
You could, and I know it's annoying, capture your POST data and turn it into SESSION variables, then repopulate input fields on browser back.
Alternatively, You can submit the form to an iframe and process, or use ajax to process and depending on the result, trigger a new page load or not.

Best way to do a 'Confirm' page?

I was wondering about the best way to implement a "Confirm Page" upon form submission. I know that it's best for the script that a form POSTs to be implemented by handling the POST data and then redirecting to another page, so the user isn't directly viewing the page that was POSTed to.
My question is about the best way to implement a "Confirm before data save" page. Do I
Have my form POST to a script, which marshals the data, puts in a GET, and redirects to the confirm page, which unmarshals and displays the data in another form, where the user can then either confirm (which causes another POST to a script that actually saves the data) or deny (which causes the user to be redirected back to the original form, with their input added)?
Have my form POST directly to the confirm page, which is displayed to the user and then, like #1, gives the user the option to confirm or deny?
Have my form GET the confirm page, which then does the expected behavior?
I feel like there is a common-sense answer to this question that I am just not getting.
If you must do this (I'd only do it for stuff involving monetary transactions or the like, personally), I'd recommend 2 resources/URIs, both of which follow the Post-Redirect-Get pattern: POST the initial cart checkout, create a "pending order" state (or similar), redirect to the page for that state. The user can then POST from that page to the next URI to create a "confirmed order" (or similar), which redirects to a receipt page or whatever.
What I've done in the past is have one page that has a 'View' area with labels and then a 'Edit' area with textboxes/dropdowns/etc. You can make them DIVs or TABLES depending on your preference.
User comes to page and gets the edit view so they can use the textboxes. Save/Submit button at the bottom.
Clicking on Save/Submit does a postback, populates the labels with the data they entered, and allows them to view/verify what they entered. Continue and Edit buttons at the bottom.
Edit is a postback and goes back to the edit view.
Continue does the actual save and redirection to a new page that displays the confirmation.
Optionally you could save the data on the confirmation page instead of the first page depending on your preference again.
Actually, you could do this ahead of the submit. In the form submit (wherever that is) add an onlick that fires a modal window with a confirmation button. My personal favorite in this situation is to use a Jquery UI Modal Confirmation dialog.
I personally fire this via means of a Jquery .click statement in the page.
So, the document won't submit until the onclick dependency has been completed and changed to "true" which the example does automatically with the included "ok" button.
I believe that this will gracefully fallback to just not require the confirmation if Javascript is turned off, which itself is becoming more and more of an "edge" case. In fact, some of my most staunch corporate clients are starting to accept limitations such as this case when Javascript is turned off....and they're way more picky that most any of us ever will be.
Then, you're free to submit to any page you'd like. Personally, I've switched all of my forms over to a Jquery .ajax submit, but that's just me. You can do it however you like.

Form Double Post Issue

I understand that double posts has been a problem with forms forever.
I am using the token server-side method to handle this issue, but I find that it doesn't seem to work flawlessly. I have the system set to create a unique token for every form, and then record that token in a SESSION after it has been posted.
The SESSION is actually an array of every form the user has ever posted (to be reset when the SESSION expires), and on each submit the system checks in_array() to see if that form has ever already been posted... if so then it stops them.
Seems like in production the system cannot record the completed token into the SESSION quick enough to deal with double clicks on the submit button. So revisiting an old page is handled fine, but the immediate double click of the submit creates a problem.
Not sure what I can do to fix this issue.
How about disabling the submit button immediately upon clicking (via Javascript, with an onClick handler)? This obviously won't fix all issues, but it might cover the cases where the system isn't quick enough to record the token into SESSION.
I have had this issue as well with something internal for the company I am working for. In my experience people click multiple times because they don't think anything is happening. What I have done is to remove the ability to submit the form and display some sort of message saying that the information is being processed.
Pop-up divs and just disabling the button work well.
I had same problem and I resolve with jQuery.
I added class singleClick in submit button there I would like to have single click and also added some javascript code
<input type="submit" class="singleClick" value="Send Request">
$(function () {
$('.singleClick').on('click', function () {
$(this).attr('disabled', true);
});
});