Mercurial > hg > isophonics-drupal-site
comparison core/tests/Drupal/FunctionalJavascriptTests/Ajax/MultiFormTest.php @ 17:129ea1e6d783
Update, including to Drupal core 8.6.10
author | Chris Cannam |
---|---|
date | Thu, 28 Feb 2019 13:21:36 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
16:c2387f117808 | 17:129ea1e6d783 |
---|---|
1 <?php | |
2 | |
3 namespace Drupal\FunctionalJavascriptTests\Ajax; | |
4 | |
5 use Drupal\Component\Render\FormattableMarkup; | |
6 use Drupal\Core\Field\FieldStorageDefinitionInterface; | |
7 use Drupal\field\Entity\FieldConfig; | |
8 use Drupal\field\Entity\FieldStorageConfig; | |
9 use Drupal\FunctionalJavascriptTests\WebDriverTestBase; | |
10 | |
11 /** | |
12 * Tests that AJAX-enabled forms work when multiple instances of the same form | |
13 * are on a page. | |
14 * | |
15 * @group Ajax | |
16 */ | |
17 class MultiFormTest extends WebDriverTestBase { | |
18 | |
19 /** | |
20 * {@inheritdoc} | |
21 */ | |
22 public static $modules = ['node', 'form_test']; | |
23 | |
24 /** | |
25 * {@inheritdoc} | |
26 */ | |
27 protected function setUp() { | |
28 parent::setUp(); | |
29 | |
30 $this->drupalCreateContentType(['type' => 'page', 'name' => 'Page']); | |
31 | |
32 // Create a multi-valued field for 'page' nodes to use for Ajax testing. | |
33 $field_name = 'field_ajax_test'; | |
34 FieldStorageConfig::create([ | |
35 'entity_type' => 'node', | |
36 'field_name' => $field_name, | |
37 'type' => 'text', | |
38 'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED, | |
39 ])->save(); | |
40 FieldConfig::create([ | |
41 'field_name' => $field_name, | |
42 'entity_type' => 'node', | |
43 'bundle' => 'page', | |
44 ])->save(); | |
45 entity_get_form_display('node', 'page', 'default') | |
46 ->setComponent($field_name, ['type' => 'text_textfield']) | |
47 ->save(); | |
48 | |
49 // Log in a user who can create 'page' nodes. | |
50 $this->drupalLogin($this->drupalCreateUser(['create page content'])); | |
51 } | |
52 | |
53 /** | |
54 * Tests that pages with the 'node_page_form' included twice work correctly. | |
55 */ | |
56 public function testMultiForm() { | |
57 // HTML IDs for elements within the field are potentially modified with | |
58 // each Ajax submission, but these variables are stable and help target the | |
59 // desired elements. | |
60 $field_name = 'field_ajax_test'; | |
61 | |
62 $form_xpath = '//form[starts-with(@id, "node-page-form")]'; | |
63 $field_xpath = '//div[contains(@class, "field--name-field-ajax-test")]'; | |
64 $button_name = $field_name . '_add_more'; | |
65 $button_value = t('Add another item'); | |
66 $button_xpath_suffix = '//input[@name="' . $button_name . '"]'; | |
67 $field_items_xpath_suffix = '//input[@type="text"]'; | |
68 | |
69 // Ensure the initial page contains both node forms and the correct number | |
70 // of field items and "add more" button for the multi-valued field within | |
71 // each form. | |
72 $this->drupalGet('form-test/two-instances-of-same-form'); | |
73 | |
74 // Wait for javascript on the page to prepare the form attributes. | |
75 $this->assertSession()->assertWaitOnAjaxRequest(); | |
76 | |
77 $session = $this->getSession(); | |
78 $page = $session->getPage(); | |
79 $fields = $page->findAll('xpath', $form_xpath . $field_xpath); | |
80 $this->assertEqual(count($fields), 2); | |
81 foreach ($fields as $field) { | |
82 $this->assertCount(1, $field->findAll('xpath', '.' . $field_items_xpath_suffix), 'Found the correct number of field items on the initial page.'); | |
83 $this->assertFieldsByValue($field->find('xpath', '.' . $button_xpath_suffix), NULL, 'Found the "add more" button on the initial page.'); | |
84 } | |
85 | |
86 $this->assertNoDuplicateIds(); | |
87 | |
88 // Submit the "add more" button of each form twice. After each corresponding | |
89 // page update, ensure the same as above. | |
90 | |
91 for ($i = 0; $i < 2; $i++) { | |
92 $forms = $page->find('xpath', $form_xpath); | |
93 foreach ($forms as $offset => $form) { | |
94 $button = $form->findButton($button_value); | |
95 $this->assertNotNull($button, 'Add Another Item button exists'); | |
96 $button->press(); | |
97 | |
98 // Wait for page update. | |
99 $this->assertSession()->assertWaitOnAjaxRequest(); | |
100 | |
101 // After AJAX request and response page will update. | |
102 $page_updated = $session->getPage(); | |
103 $field = $page_updated->findAll('xpath', '.' . $field_xpath); | |
104 $this->assertEqual(count($field[0]->find('xpath', '.' . $field_items_xpath_suffix)), $i + 2, 'Found the correct number of field items after an AJAX submission.'); | |
105 $this->assertFieldsByValue($field[0]->find('xpath', '.' . $button_xpath_suffix), NULL, 'Found the "add more" button after an AJAX submission.'); | |
106 $this->assertNoDuplicateIds(); | |
107 } | |
108 } | |
109 } | |
110 | |
111 /** | |
112 * Asserts that each HTML ID is used for just a single element on the page. | |
113 * | |
114 * @param string $message | |
115 * (optional) A message to display with the assertion. | |
116 */ | |
117 protected function assertNoDuplicateIds($message = '') { | |
118 $args = ['@url' => $this->getUrl()]; | |
119 | |
120 if (!$elements = $this->xpath('//*[@id]')) { | |
121 $this->fail(new FormattableMarkup('The page @url contains no HTML IDs.', $args)); | |
122 return; | |
123 } | |
124 | |
125 $message = $message ?: new FormattableMarkup('The page @url does not contain duplicate HTML IDs', $args); | |
126 | |
127 $seen_ids = []; | |
128 foreach ($elements as $element) { | |
129 $id = $element->getAttribute('id'); | |
130 if (isset($seen_ids[$id])) { | |
131 $this->fail($message); | |
132 return; | |
133 } | |
134 $seen_ids[$id] = TRUE; | |
135 } | |
136 $this->assertTrue(TRUE, $message); | |
137 } | |
138 | |
139 } |