MultiFormTest.php
Same filename in other branches
Namespace
Drupal\FunctionalJavascriptTests\AjaxFile
-
core/
tests/ Drupal/ FunctionalJavascriptTests/ Ajax/ MultiFormTest.php
View source
<?php
namespace Drupal\FunctionalJavascriptTests\Ajax;
use Drupal\Component\Render\FormattableMarkup;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\FunctionalJavascriptTests\WebDriverTestBase;
/**
* Tests that AJAX-enabled forms work when multiple instances of the same form
* are on a page.
*
* @group Ajax
*/
class MultiFormTest extends WebDriverTestBase {
/**
* {@inheritdoc}
*/
public static $modules = [
'node',
'form_test',
];
/**
* {@inheritdoc}
*/
protected $defaultTheme = 'stark';
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->drupalCreateContentType([
'type' => 'page',
'name' => 'Page',
]);
// Create a multi-valued field for 'page' nodes to use for Ajax testing.
$field_name = 'field_ajax_test';
FieldStorageConfig::create([
'entity_type' => 'node',
'field_name' => $field_name,
'type' => 'text',
'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED,
])->save();
FieldConfig::create([
'field_name' => $field_name,
'entity_type' => 'node',
'bundle' => 'page',
])->save();
\Drupal::service('entity_display.repository')->getFormDisplay('node', 'page', 'default')
->setComponent($field_name, [
'type' => 'text_textfield',
])
->save();
// Log in a user who can create 'page' nodes.
$this->drupalLogin($this->drupalCreateUser([
'create page content',
]));
}
/**
* Tests that pages with the 'node_page_form' included twice work correctly.
*/
public function testMultiForm() {
// HTML IDs for elements within the field are potentially modified with
// each Ajax submission, but these variables are stable and help target the
// desired elements.
$field_name = 'field_ajax_test';
$form_xpath = '//form[starts-with(@id, "node-page-form")]';
$field_xpath = '//div[contains(@class, "field--name-field-ajax-test")]';
$button_name = $field_name . '_add_more';
$button_value = t('Add another item');
$button_xpath_suffix = '//input[@name="' . $button_name . '"]';
$field_items_xpath_suffix = '//input[@type="text"]';
// Ensure the initial page contains both node forms and the correct number
// of field items and "add more" button for the multi-valued field within
// each form.
$this->drupalGet('form-test/two-instances-of-same-form');
// Wait for javascript on the page to prepare the form attributes.
$this->assertSession()
->assertWaitOnAjaxRequest();
$session = $this->getSession();
$page = $session->getPage();
$fields = $page->findAll('xpath', $form_xpath . $field_xpath);
$this->assertCount(2, $fields);
foreach ($fields as $field) {
$this->assertCount(1, $field->findAll('xpath', '.' . $field_items_xpath_suffix), 'Found the correct number of field items on the initial page.');
$this->assertFieldsByValue($field->find('xpath', '.' . $button_xpath_suffix), NULL, 'Found the "add more" button on the initial page.');
}
$this->assertNoDuplicateIds();
// Submit the "add more" button of each form twice. After each corresponding
// page update, ensure the same as above.
for ($i = 0; $i < 2; $i++) {
$forms = $page->find('xpath', $form_xpath);
foreach ($forms as $offset => $form) {
$button = $form->findButton($button_value);
$this->assertNotNull($button, 'Add Another Item button exists');
$button->press();
// Wait for page update.
$this->assertSession()
->assertWaitOnAjaxRequest();
// After AJAX request and response page will update.
$page_updated = $session->getPage();
$field = $page_updated->findAll('xpath', '.' . $field_xpath);
$this->assertCount($i + 2, $field[0]->find('xpath', '.' . $field_items_xpath_suffix), 'Found the correct number of field items after an AJAX submission.');
$this->assertFieldsByValue($field[0]->find('xpath', '.' . $button_xpath_suffix), NULL, 'Found the "add more" button after an AJAX submission.');
$this->assertNoDuplicateIds();
}
}
}
/**
* Asserts that each HTML ID is used for just a single element on the page.
*
* @param string $message
* (optional) A message to display with the assertion.
*/
protected function assertNoDuplicateIds($message = '') {
$args = [
'@url' => $this->getUrl(),
];
if (!($elements = $this->xpath('//*[@id]'))) {
$this->fail(new FormattableMarkup('The page @url contains no HTML IDs.', $args));
return;
}
$message = $message ?: new FormattableMarkup('The page @url does not contain duplicate HTML IDs', $args);
$seen_ids = [];
foreach ($elements as $element) {
$id = $element->getAttribute('id');
if (isset($seen_ids[$id])) {
$this->fail($message);
return;
}
$seen_ids[$id] = TRUE;
}
$this->assertTrue(TRUE, $message);
}
}
Classes
Title | Deprecated | Summary |
---|---|---|
MultiFormTest | Tests that AJAX-enabled forms work when multiple instances of the same form are on a page. |
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.