8a36c8489f51954974848b6afa58c139ffa9dca0
[yaffs-website] / web / core / modules / field_layout / tests / src / FunctionalJavascript / FieldLayoutTest.php
1 <?php
2
3 namespace Drupal\Tests\field_layout\FunctionalJavascript;
4
5 use Drupal\entity_test\Entity\EntityTest;
6 use Drupal\FunctionalJavascriptTests\WebDriverTestBase;
7
8 /**
9  * Tests using field layout for entity displays.
10  *
11  * @group field_layout
12  */
13 class FieldLayoutTest extends WebDriverTestBase {
14
15   /**
16    * {@inheritdoc}
17    */
18   public static $modules = ['field_layout', 'field_ui', 'field_layout_test', 'layout_test'];
19
20   /**
21    * {@inheritdoc}
22    */
23   protected function setUp() {
24     parent::setUp();
25
26     $entity = EntityTest::create([
27       'name' => 'The name for this entity',
28       'field_test_text' => [
29         ['value' => 'The field test text value'],
30       ],
31     ]);
32     $entity->save();
33     $this->drupalLogin($this->drupalCreateUser([
34       'access administration pages',
35       'view test entity',
36       'administer entity_test content',
37       'administer entity_test fields',
38       'administer entity_test display',
39       'administer entity_test form display',
40       'view the administration theme',
41     ]));
42   }
43
44   /**
45    * Tests that layouts are unique per view mode.
46    */
47   public function testEntityViewModes() {
48     // By default, the field is not visible.
49     $this->drupalGet('entity_test/1/test');
50     $this->assertSession()->elementNotExists('css', '.layout__region--content .field--name-field-test-text');
51     $this->drupalGet('entity_test/1');
52     $this->assertSession()->elementNotExists('css', '.layout__region--content .field--name-field-test-text');
53
54     // Change the layout for the "test" view mode. See
55     // core.entity_view_mode.entity_test.test.yml.
56     $this->drupalGet('entity_test/structure/entity_test/display');
57     $this->click('#edit-modes');
58     $this->getSession()->getPage()->checkField('display_modes_custom[test]');
59     $this->submitForm([], 'Save');
60     $this->clickLink('configure them');
61     $this->getSession()->getPage()->pressButton('Show row weights');
62     $this->getSession()->getPage()->selectFieldOption('fields[field_test_text][region]', 'content');
63     $this->assertSession()->assertWaitOnAjaxRequest();
64     $this->submitForm([], 'Save');
65
66     // Each view mode has a different layout.
67     $this->drupalGet('entity_test/1/test');
68     $this->assertSession()->elementExists('css', '.layout__region--content .field--name-field-test-text');
69     $this->drupalGet('entity_test/1');
70     $this->assertSession()->elementNotExists('css', '.layout__region--content .field--name-field-test-text');
71   }
72
73   /**
74    * Tests the use of field layout for entity form displays.
75    */
76   public function testEntityForm() {
77     // By default, the one-column layout is used.
78     $this->drupalGet('entity_test/manage/1/edit');
79     $this->assertFieldInRegion('field_test_text[0][value]', 'content');
80
81     // The one-column layout is in use.
82     $this->drupalGet('entity_test/structure/entity_test/form-display');
83     $this->assertEquals(['Content', 'Disabled'], $this->getRegionTitles());
84
85     // Switch the layout to two columns.
86     $this->click('#edit-field-layouts');
87     $this->getSession()->getPage()->selectFieldOption('field_layout', 'layout_twocol');
88     $this->assertSession()->assertWaitOnAjaxRequest();
89     $this->submitForm([], 'Save');
90
91     // The field is moved to the default region for the new layout.
92     $this->assertSession()->pageTextContains('Your settings have been saved.');
93     $this->assertEquals(['Top', 'First', 'Second', 'Bottom', 'Disabled'], $this->getRegionTitles());
94
95     $this->drupalGet('entity_test/manage/1/edit');
96     // No fields are visible, and the regions don't display when empty.
97     $this->assertFieldInRegion('field_test_text[0][value]', 'first');
98     $this->assertSession()->elementExists('css', '.layout__region--first .field--name-field-test-text');
99
100     // After a refresh the new regions are still there.
101     $this->drupalGet('entity_test/structure/entity_test/form-display');
102     $this->assertEquals(['Top', 'First', 'Second', 'Bottom', 'Disabled'], $this->getRegionTitles());
103     $this->assertSession()->waitForElement('css', '.tabledrag-handle');
104     $id = $this->getSession()->getPage()->find('css', '[name="form_build_id"]')->getValue();
105
106     // Drag the field to the second region.
107     $field_test_text_row = $this->getSession()->getPage()->find('css', '#field-test-text');
108     $second_region_row = $this->getSession()->getPage()->find('css', '.region-second-message');
109     $field_test_text_row->find('css', '.handle')->dragTo($second_region_row);
110     $this->assertSession()->assertWaitOnAjaxRequest();
111     $this->assertSession()->waitForElement('css', "[name='form_build_id']:not([value='$id'])");
112     $this->submitForm([], 'Save');
113     $this->assertSession()->pageTextContains('Your settings have been saved.');
114
115     // The new layout is used.
116     $this->drupalGet('entity_test/manage/1/edit');
117     $this->assertSession()->elementExists('css', '.layout__region--second .field--name-field-test-text');
118     $this->assertFieldInRegion('field_test_text[0][value]', 'second');
119
120     // Move the field to the second region without tabledrag.
121     $this->drupalGet('entity_test/structure/entity_test/form-display');
122     $this->getSession()->getPage()->pressButton('Show row weights');
123     $this->getSession()->getPage()->selectFieldOption('fields[field_test_text][region]', 'second');
124     $this->assertSession()->assertWaitOnAjaxRequest();
125     $this->submitForm([], 'Save');
126     $this->assertSession()->pageTextContains('Your settings have been saved.');
127
128     // The updated region is used.
129     $this->drupalGet('entity_test/manage/1/edit');
130     $this->assertFieldInRegion('field_test_text[0][value]', 'second');
131
132     // The layout is still in use without Field UI.
133     $this->container->get('module_installer')->uninstall(['field_ui']);
134     $this->drupalGet('entity_test/manage/1/edit');
135     $this->assertFieldInRegion('field_test_text[0][value]', 'second');
136   }
137
138   /**
139    * Tests the use of field layout for entity view displays.
140    */
141   public function testEntityView() {
142     // The one-column layout is in use.
143     $this->drupalGet('entity_test/structure/entity_test/display');
144     $this->assertEquals(['Content', 'Disabled'], $this->getRegionTitles());
145
146     // Switch the layout to two columns.
147     $this->click('#edit-field-layouts');
148     $this->getSession()->getPage()->selectFieldOption('field_layout', 'layout_twocol');
149     $this->assertSession()->assertWaitOnAjaxRequest();
150     $this->submitForm([], 'Save');
151
152     $this->assertSession()->pageTextContains('Your settings have been saved.');
153     $this->assertEquals(['Top', 'First', 'Second', 'Bottom', 'Disabled'], $this->getRegionTitles());
154
155     $this->drupalGet('entity_test/1');
156     // No fields are visible, and the regions don't display when empty.
157     $this->assertSession()->elementNotExists('css', '.layout--twocol');
158     $this->assertSession()->elementNotExists('css', '.layout__region');
159     $this->assertSession()->elementNotExists('css', '.field--name-field-test-text');
160
161     // After a refresh the new regions are still there.
162     $this->drupalGet('entity_test/structure/entity_test/display');
163     $this->assertEquals(['Top', 'First', 'Second', 'Bottom', 'Disabled'], $this->getRegionTitles());
164     $this->assertSession()->waitForElement('css', '.tabledrag-handle');
165     $id = $this->getSession()->getPage()->find('css', '[name="form_build_id"]')->getValue();
166
167     // Drag the field to the first region.
168     $this->assertTrue($this->assertSession()->optionExists('fields[field_test_text][region]', 'hidden')->isSelected());
169     $field_test_text_row = $this->getSession()->getPage()->find('css', '#field-test-text');
170     $first_region_row = $this->getSession()->getPage()->find('css', '.region-first-message');
171     $field_test_text_row->find('css', '.handle')->dragTo($first_region_row);
172     $this->assertSession()->assertWaitOnAjaxRequest();
173     $this->assertFalse($this->assertSession()->optionExists('fields[field_test_text][region]', 'hidden')->isSelected());
174     $this->assertSession()->waitForElement('css', "[name='form_build_id']:not([value='$id'])");
175     $this->submitForm([], 'Save');
176     $this->assertSession()->pageTextContains('Your settings have been saved.');
177
178     // The new layout is used.
179     $this->drupalGet('entity_test/1');
180     $this->assertSession()->elementExists('css', '.layout--twocol');
181     $this->assertSession()->elementExists('css', '.layout__region--first .field--name-field-test-text');
182
183     // Move the field to the second region without tabledrag.
184     $this->drupalGet('entity_test/structure/entity_test/display');
185     $this->getSession()->getPage()->pressButton('Show row weights');
186     $this->getSession()->getPage()->selectFieldOption('fields[field_test_text][region]', 'second');
187     $this->assertSession()->assertWaitOnAjaxRequest();
188     $this->submitForm([], 'Save');
189     $this->assertSession()->pageTextContains('Your settings have been saved.');
190
191     // The updated region is used.
192     $this->drupalGet('entity_test/1');
193     $this->assertSession()->elementExists('css', '.layout__region--second .field--name-field-test-text');
194
195     // The layout is still in use without Field UI.
196     $this->container->get('module_installer')->uninstall(['field_ui']);
197     $this->drupalGet('entity_test/1');
198     $this->assertSession()->elementExists('css', '.layout--twocol');
199     $this->assertSession()->elementExists('css', '.layout__region--second .field--name-field-test-text');
200   }
201
202   /**
203    * Tests layout plugins with forms.
204    */
205   public function testLayoutForms() {
206     $this->drupalGet('entity_test/structure/entity_test/display');
207     // Switch to a field layout with settings.
208     $this->click('#edit-field-layouts');
209
210     // Test switching between layouts with and without forms.
211     $this->getSession()->getPage()->selectFieldOption('field_layout', 'layout_test_plugin');
212     $this->assertSession()->assertWaitOnAjaxRequest();
213     $this->assertSession()->fieldExists('settings_wrapper[layout_settings][setting_1]');
214
215     $this->getSession()->getPage()->selectFieldOption('field_layout', 'layout_test_2col');
216     $this->assertSession()->assertWaitOnAjaxRequest();
217     $this->assertSession()->fieldNotExists('settings_wrapper[layout_settings][setting_1]');
218
219     $this->getSession()->getPage()->selectFieldOption('field_layout', 'layout_test_plugin');
220     $this->assertSession()->assertWaitOnAjaxRequest();
221     $this->assertSession()->fieldExists('settings_wrapper[layout_settings][setting_1]');
222
223     // Move the test field to the content region.
224     $this->getSession()->getPage()->pressButton('Show row weights');
225     $this->getSession()->getPage()->selectFieldOption('fields[field_test_text][region]', 'content');
226     $this->assertSession()->assertWaitOnAjaxRequest();
227     $this->submitForm([], 'Save');
228
229     $this->drupalGet('entity_test/1');
230     $this->assertSession()->pageTextContains('Blah: Default');
231
232     // Update the field layout settings.
233     $this->drupalGet('entity_test/structure/entity_test/display');
234     $this->click('#edit-field-layouts');
235     $this->getSession()->getPage()->fillField('settings_wrapper[layout_settings][setting_1]', 'Test text');
236     $this->submitForm([], 'Save');
237
238     $this->drupalGet('entity_test/1');
239     $this->assertSession()->pageTextContains('Blah: Test text');
240   }
241
242   /**
243    * Tests changing the formatter and region at the same time.
244    */
245   public function testChangingFormatterAndRegion() {
246     $assert_session = $this->assertSession();
247     $page = $this->getSession()->getPage();
248
249     // Add the test field to the content region.
250     $this->drupalGet('entity_test/structure/entity_test/display');
251     $page->find('css', '#field-test-text .handle')->dragTo($page->find('css', '.region-content-message'));
252     $assert_session->assertWaitOnAjaxRequest();
253     $page->pressButton('Save');
254     $assert_session->fieldValueEquals('fields[field_test_text][region]', 'content');
255     $assert_session->fieldValueEquals('fields[field_test_text][type]', 'text_default');
256
257     // Switch the layout to two columns.
258     $this->click('#edit-field-layouts');
259     $page->selectFieldOption('field_layout', 'layout_twocol');
260     $assert_session->assertWaitOnAjaxRequest();
261     $page->pressButton('Save');
262     $assert_session->fieldValueEquals('fields[field_test_text][region]', 'first');
263
264     // Change the formatter and move to another region.
265     $page->selectFieldOption('fields[field_test_text][type]', 'text_trimmed');
266     $assert_session->assertWaitOnAjaxRequest();
267     $page->find('css', '#field-test-text .handle')->dragTo($page->find('css', '.region-second-message'));
268     $assert_session->assertWaitOnAjaxRequest();
269     $page->pressButton('Save');
270
271     // Assert that both the formatter and region change are persisted.
272     $assert_session->fieldValueEquals('fields[field_test_text][region]', 'second');
273     $assert_session->fieldValueEquals('fields[field_test_text][type]', 'text_trimmed');
274   }
275
276   /**
277    * Gets the region titles on the page.
278    *
279    * @return string[]
280    *   An array of region titles.
281    */
282   protected function getRegionTitles() {
283     $region_titles = [];
284     $region_title_elements = $this->getSession()->getPage()->findAll('css', '.region-title td');
285     /** @var \Behat\Mink\Element\NodeElement[] $region_title_elements */
286     foreach ($region_title_elements as $region_title_element) {
287       $region_titles[] = $region_title_element->getText();
288     }
289     return $region_titles;
290   }
291
292   /**
293    * Asserts that a field exists in a given region.
294    *
295    * @param string $field_selector
296    *   The field selector, one of field id|name|label|value.
297    * @param string $region_name
298    *   The machine name of the region.
299    */
300   protected function assertFieldInRegion($field_selector, $region_name) {
301     $region_element = $this->getSession()->getPage()->find('css', ".layout__region--$region_name");
302     $this->assertNotNull($region_element);
303     $this->assertSession()->fieldExists($field_selector, $region_element);
304   }
305
306 }