diff --git a/core/modules/system/src/Tests/Ajax/MultiFormTest.php b/core/modules/system/src/Tests/Ajax/MultiFormTest.php deleted file mode 100644 index 96844ed051a1bdd4c4cdd1b06c278173f127983d..0000000000000000000000000000000000000000 --- a/core/modules/system/src/Tests/Ajax/MultiFormTest.php +++ /dev/null @@ -1,98 +0,0 @@ -<?php - -namespace Drupal\system\Tests\Ajax; - -use Drupal\Core\Field\FieldStorageDefinitionInterface; -use Drupal\field\Entity\FieldConfig; -use Drupal\field\Entity\FieldStorageConfig; - -/** - * Tests that AJAX-enabled forms work when multiple instances of the same form - * are on a page. - * - * @group Ajax - */ -class MultiFormTest extends AjaxTestBase { - - /** - * Modules to enable. - * - * @var array - */ - public static $modules = ['form_test']; - - 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(); - entity_get_form_display('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'); - - $fields = $this->xpath($form_xpath . $field_xpath); - $this->assertEqual(count($fields), 2); - foreach ($fields as $field) { - $this->assertEqual(count($field->xpath('.' . $field_items_xpath_suffix)), 1, 'Found the correct number of field items on the initial page.'); - $this->assertFieldsByValue($field->xpath('.' . $button_xpath_suffix), NULL, 'Found the "add more" button on the initial page.'); - } - - $this->assertNoDuplicateIds(t('Initial page contains unique IDs'), 'Other'); - - // 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 = $this->xpath($form_xpath); - foreach ($forms as $offset => $form) { - $form_html_id = (string) $form['id']; - $this->drupalPostAjaxForm(NULL, [], [$button_name => $button_value], NULL, [], [], $form_html_id); - $form = $this->xpath($form_xpath)[$offset]; - $field = $form->xpath('.' . $field_xpath); - - $this->assertEqual(count($field[0]->xpath('.' . $field_items_xpath_suffix)), $i + 2, 'Found the correct number of field items after an AJAX submission.'); - $this->assertFieldsByValue($field[0]->xpath('.' . $button_xpath_suffix), NULL, 'Found the "add more" button after an AJAX submission.'); - $this->assertNoDuplicateIds(t('Updated page contains unique IDs'), 'Other'); - } - } - } - -} diff --git a/core/tests/Drupal/FunctionalJavascriptTests/Ajax/MultiFormTest.php b/core/tests/Drupal/FunctionalJavascriptTests/Ajax/MultiFormTest.php new file mode 100644 index 0000000000000000000000000000000000000000..fe3fcf2f5084bd3ec01ed0efb9228ff7522bf78a --- /dev/null +++ b/core/tests/Drupal/FunctionalJavascriptTests/Ajax/MultiFormTest.php @@ -0,0 +1,139 @@ +<?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 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(); + entity_get_form_display('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->assertEqual(count($fields), 2); + foreach ($fields as $field) { + $this->assertEqual(count($field->find('xpath', '.' . $field_items_xpath_suffix)), 1, '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->assertEqual(count($field[0]->find('xpath', '.' . $field_items_xpath_suffix)), $i + 2, '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); + } + +}