There are many tests are calling drupalPostAjaxForm() when a call to drupalPostForm() would be sufficient. From what I have seen this is true for contrib modules as well. Simply changing the calls to drupalPostForm() is usually sufficient to make those calls work again when tests are being converted and BTB is faster than JavascriptTestBase. For that reason I propose adding drupalPostAjaxForm() to BTB as an alias to drupalPostForm() to aid in the initial conversion and offer a bit more deprecated backwards compatibility.

A few examples of drupalPostAjaxForm() to drupalPostForm() conversion:

Potential patch for #2794347: Convert web tests to browser tests for field_ui module.

Potential patch for #2753889: Convert ParagraphsTestBase and the easy-to-convert tests extending it to BrowserTestBase and some of the other child issues of #2752659: [META] Convert SimpleTest Tests to PHPUnit.

Comments

jmuzz created an issue. See original summary.

jmuzz’s picture

dawehner’s picture

Just aliasing doesn't help. You need to replicate the ajax behaviour.

Instead of doing that, we should IMHO convert them to JTB.

jmuzz’s picture

Maybe I'm missing something or drawing conclusions from a small sample size, but most of the tests I've seen using drupalPostAjaxForm() don't need to replicate the ajax behaviour. Changing the calls in the individual tests from drupalPostAjaxForm() to drupalPostForm() does seem to work a lot of the time. It may be possible that people have used drupalPostAjaxForm() not because it's needed but because many of the forms can make optional use of javascript so at the time of writing the tests either of the functions would have been just as good as the other and neither of them would have incurred a significant performance penalty like switching to JavascriptTestBase now would. I have not seen many cases where the assertions made after the calls are looking for anything that depends on ajax functionality.

dawehner’s picture

They all rely on \Drupal\simpletest\WebTestBase::drupalProcessAjaxResponse which fakes some ajax behaviour.
That PHP code emulates what otherwise the JS tends to do.

jmuzz’s picture

I can do a better job of explaining this so it can be understood:

Some of the drupalPostAjaxForm() calls probably do rely on drupalProcessAjaxResponse(). So far the ones I've seen work without it, often with no change other than making drupalPostAjaxForm() into drupalPostForm(). There seems to be the assumption that if somebody used drupalPostAjaxForm() that the author was consciously making the decision to test the ajax functionality on the form, but wouldn't this evidence seem to suggest that much of the time they are just writing tests for general form functionality and decided to use drupalPostAjaxForm() because drupal core adds some optional ajax to their form or just because they can?

I'll give a specific example from core. The field_ui module uses drupalPostAjaxForm() in ManageDisplayTest to test what happens when clicking the settings gear buttons on the Display forms. I looked at field_ui.js and I didn't see anything specific to those settings buttons. Those calls work in BTB by being changed to drupalPostForm().

dawehner’s picture

I'll give a specific example from core. The field_ui module uses drupalPostAjaxForm() in ManageDisplayTest to test what happens when clicking the settings gear buttons on the Display forms. I looked at field_ui.js and I didn't see anything specific to those settings buttons. Those calls work in BTB by being changed to drupalPostForm().

Well, in this case we are implicit testing that our #ajax is set properly. drupalPostForm() would not test that

jhodgdon’s picture

Title: Alias drupalPostAjaxForm() to drupalPostForm() in BTB » Add drupalPostAjaxForm() or equivalent functionality to BrowserTestBase
Related issues: +#2808377: WebTestBase::drupalProcessAjaxResponse() is not handling UTF-8 well

So, drupalPostAjaxForm() does two things:

a) Figures out what to put into drupalPostForm() and posts the Ajax request.

b) Processes the returned Ajax response to modify the HTML page, by using PHP to simulate what the JS in ajax.js would be doing. Normally, this would be adding a piece to a form, such as on the Manage Display test: when you click the gear icon, you get a new form for the settings.

If you just do drupalPostForm, you skip step (b) and the page is not changed. In #6, it is stated that field_ui.js does nothing special, which is most likely true. That is because it is the generic ajax.js that processes the form changes. The PHP in Form API module generates Ajax 'commands', which have data attached to them, such as "Insert a bunch of HTML in this div". The generic ajax.js knows how to read the Ajax commands and process them in a generic way. That is the beauty of the Drupal Ajax system -- each module doesn't have to have its own special Ajax processing code on the browser site, it just has to return its response in standard Drupal Ajax command format and the generic ajax.js takes care of it.

So, we still need the drupalProcessAjaxResponse() code, which processes the most common types of Drupal Ajax command (the one that says "replace the HTML with this new HTML in this one area", and the one that says "update the JS settings"), to simulate what the JS code in ajax.js would be doing.

Hope this explanation helps... Changing title because a pure alias is not really going to work with Field UI and other tests that actually need the Ajax response to be processed.

Anyway, the reason I was posting anything here at all is I found a bug in the WebTestBase::drupalProcessAjaxResponse() code and wanted to link that issue here.

dawehner’s picture

Thank you @jhodgdon for 100% clarifying what is going on.
As you said we process the common Drupal Ajax tests, which might or might not be working. I believe strongly that #2809161: Convert Javascript/AJAX testing to use JavascriptTestBase is what we should actually do. drupalPostAjaxForm is just a workaround as we didn't had JS tests.

jhodgdon’s picture

Ah, I didn't know about that issue. Commenting there...

dawehner’s picture

I kinda think we settled on closed (won't fix) here?

klausi’s picture

Status: Active » Closed (won't fix)

Agreed.

For existing tests we can do 2 things:

1) Change to drupalPostForm() to test the behavior with Javascript disabled.

2) Write a new JavascriptTestBase test which performs the test with javascript enabled.