3 namespace Drupal\Tests\field_layout\FunctionalJavascript;
5 use Drupal\entity_test\Entity\EntityTest;
6 use Drupal\FunctionalJavascriptTests\JavascriptTestBase;
9 * Tests using field layout for entity displays.
13 class FieldLayoutTest extends JavascriptTestBase {
18 public static $modules = ['field_layout', 'field_ui', 'field_layout_test', 'layout_test'];
23 protected function setUp() {
26 $entity = EntityTest::create([
27 'name' => 'The name for this entity',
28 'field_test_text' => [[
29 'value' => 'The field test text value',
33 $this->drupalLogin($this->drupalCreateUser([
34 'access administration pages',
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',
45 * Tests that layouts are unique per view mode.
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');
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');
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');
74 * Tests the use of field layout for entity form displays.
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');
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());
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');
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());
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');
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());
104 // Drag the field to the second region.
105 $field_test_text_row = $this->getSession()->getPage()->find('css', '#field-test-text');
106 $second_region_row = $this->getSession()->getPage()->find('css', '.region-second-message');
107 $field_test_text_row->find('css', '.handle')->dragTo($second_region_row);
108 $this->assertSession()->assertWaitOnAjaxRequest();
109 $this->submitForm([], 'Save');
110 $this->assertSession()->pageTextContains('Your settings have been saved.');
112 // The new layout is used.
113 $this->drupalGet('entity_test/manage/1/edit');
114 $this->assertSession()->elementExists('css', '.layout__region--second .field--name-field-test-text');
115 $this->assertFieldInRegion('field_test_text[0][value]', 'second');
117 // Move the field to the second region without tabledrag.
118 $this->drupalGet('entity_test/structure/entity_test/form-display');
119 $this->getSession()->getPage()->pressButton('Show row weights');
120 $this->getSession()->getPage()->selectFieldOption('fields[field_test_text][region]', 'second');
121 $this->assertSession()->assertWaitOnAjaxRequest();
122 $this->submitForm([], 'Save');
123 $this->assertSession()->pageTextContains('Your settings have been saved.');
125 // The updated region is used.
126 $this->drupalGet('entity_test/manage/1/edit');
127 $this->assertFieldInRegion('field_test_text[0][value]', 'second');
129 // The layout is still in use without Field UI.
130 $this->container->get('module_installer')->uninstall(['field_ui']);
131 $this->drupalGet('entity_test/manage/1/edit');
132 $this->assertFieldInRegion('field_test_text[0][value]', 'second');
136 * Tests the use of field layout for entity view displays.
138 public function testEntityView() {
139 // The one-column layout is in use.
140 $this->drupalGet('entity_test/structure/entity_test/display');
141 $this->assertEquals(['Content', 'Disabled'], $this->getRegionTitles());
143 // Switch the layout to two columns.
144 $this->click('#edit-field-layouts');
145 $this->getSession()->getPage()->selectFieldOption('field_layout', 'layout_twocol');
146 $this->assertSession()->assertWaitOnAjaxRequest();
147 $this->submitForm([], 'Save');
149 $this->assertSession()->pageTextContains('Your settings have been saved.');
150 $this->assertEquals(['Top', 'First', 'Second', 'Bottom', 'Disabled'], $this->getRegionTitles());
152 $this->drupalGet('entity_test/1');
153 // No fields are visible, and the regions don't display when empty.
154 $this->assertSession()->elementNotExists('css', '.layout--twocol');
155 $this->assertSession()->elementNotExists('css', '.layout__region');
156 $this->assertSession()->elementNotExists('css', '.field--name-field-test-text');
158 // After a refresh the new regions are still there.
159 $this->drupalGet('entity_test/structure/entity_test/display');
160 $this->assertEquals(['Top', 'First', 'Second', 'Bottom', 'Disabled'], $this->getRegionTitles());
162 // Drag the field to the first region.
163 $this->assertTrue($this->assertSession()->optionExists('fields[field_test_text][region]', 'hidden')->isSelected());
164 $field_test_text_row = $this->getSession()->getPage()->find('css', '#field-test-text');
165 $first_region_row = $this->getSession()->getPage()->find('css', '.region-first-message');
166 $field_test_text_row->find('css', '.handle')->dragTo($first_region_row);
167 $this->assertSession()->assertWaitOnAjaxRequest();
168 $this->assertFalse($this->assertSession()->optionExists('fields[field_test_text][region]', 'hidden')->isSelected());
169 $this->submitForm([], 'Save');
170 $this->assertSession()->pageTextContains('Your settings have been saved.');
172 // The new layout is used.
173 $this->drupalGet('entity_test/1');
174 $this->assertSession()->elementExists('css', '.layout--twocol');
175 $this->assertSession()->elementExists('css', '.layout__region--first .field--name-field-test-text');
177 // Move the field to the second region without tabledrag.
178 $this->drupalGet('entity_test/structure/entity_test/display');
179 $this->getSession()->getPage()->pressButton('Show row weights');
180 $this->getSession()->getPage()->selectFieldOption('fields[field_test_text][region]', 'second');
181 $this->assertSession()->assertWaitOnAjaxRequest();
182 $this->submitForm([], 'Save');
183 $this->assertSession()->pageTextContains('Your settings have been saved.');
185 // The updated region is used.
186 $this->drupalGet('entity_test/1');
187 $this->assertSession()->elementExists('css', '.layout__region--second .field--name-field-test-text');
189 // The layout is still in use without Field UI.
190 $this->container->get('module_installer')->uninstall(['field_ui']);
191 $this->drupalGet('entity_test/1');
192 $this->assertSession()->elementExists('css', '.layout--twocol');
193 $this->assertSession()->elementExists('css', '.layout__region--second .field--name-field-test-text');
197 * Tests layout plugins with forms.
199 public function testLayoutForms() {
200 $this->drupalGet('entity_test/structure/entity_test/display');
201 // Switch to a field layout with settings.
202 $this->click('#edit-field-layouts');
204 // Test switching between layouts with and without forms.
205 $this->getSession()->getPage()->selectFieldOption('field_layout', 'layout_test_plugin');
206 $this->assertSession()->assertWaitOnAjaxRequest();
207 $this->assertSession()->fieldExists('settings_wrapper[layout_settings][setting_1]');
209 $this->getSession()->getPage()->selectFieldOption('field_layout', 'layout_test_2col');
210 $this->assertSession()->assertWaitOnAjaxRequest();
211 $this->assertSession()->fieldNotExists('settings_wrapper[layout_settings][setting_1]');
213 $this->getSession()->getPage()->selectFieldOption('field_layout', 'layout_test_plugin');
214 $this->assertSession()->assertWaitOnAjaxRequest();
215 $this->assertSession()->fieldExists('settings_wrapper[layout_settings][setting_1]');
217 // Move the test field to the content region.
218 $this->getSession()->getPage()->pressButton('Show row weights');
219 $this->getSession()->getPage()->selectFieldOption('fields[field_test_text][region]', 'content');
220 $this->assertSession()->assertWaitOnAjaxRequest();
221 $this->submitForm([], 'Save');
223 $this->drupalGet('entity_test/1');
224 $this->assertSession()->pageTextContains('Blah: Default');
226 // Update the field layout settings.
227 $this->drupalGet('entity_test/structure/entity_test/display');
228 $this->click('#edit-field-layouts');
229 $this->getSession()->getPage()->fillField('settings_wrapper[layout_settings][setting_1]', 'Test text');
230 $this->submitForm([], 'Save');
232 $this->drupalGet('entity_test/1');
233 $this->assertSession()->pageTextContains('Blah: Test text');
237 * Gets the region titles on the page.
240 * An array of region titles.
242 protected function getRegionTitles() {
244 $region_title_elements = $this->getSession()->getPage()->findAll('css', '.region-title td');
245 /** @var \Behat\Mink\Element\NodeElement[] $region_title_elements */
246 foreach ($region_title_elements as $region_title_element) {
247 $region_titles[] = $region_title_element->getText();
249 return $region_titles;
253 * Asserts that a field exists in a given region.
255 * @param string $field_selector
256 * The field selector, one of field id|name|label|value.
257 * @param string $region_name
258 * The machine name of the region.
260 protected function assertFieldInRegion($field_selector, $region_name) {
261 $region_element = $this->getSession()->getPage()->find('css', ".layout__region--$region_name");
262 $this->assertNotNull($region_element);
263 $this->assertSession()->fieldExists($field_selector, $region_element);