3 namespace Drupal\Tests\system\FunctionalJavascript\Form;
5 use Drupal\FunctionalJavascriptTests\WebDriverTestBase;
8 * Tests that FAPI correctly determines the triggering element.
12 class TriggeringElementTest extends WebDriverTestBase {
17 protected static $modules = ['form_test'];
20 * Tests the the triggering element when no button information is included.
22 * Test the determination of the triggering element when no button
23 * information is included in the POST data, as is sometimes the case when
24 * the ENTER key is pressed in a textfield in Internet Explorer.
26 public function testNoButtonInfoInPost() {
27 $path = '/form-test/clicked-button';
28 $form_html_id = 'form-test-clicked-button';
30 // Ensure submitting a form with no buttons results in no triggering element
31 // and the form submit handler not running.
32 $this->drupalGet($path);
34 $assert_session = $this->assertSession();
35 $this->getSession()->getDriver()->submitForm('//form[@id="' . $form_html_id . '"]');
36 $assert_session->pageTextContains('There is no clicked button.');
37 $assert_session->pageTextNotContains('Submit handler for form_test_clicked_button executed.');
39 // Ensure submitting a form with one or more submit buttons results in the
40 // triggering element being set to the first one the user has access to. An
41 // argument with 'r' in it indicates a restricted (#access=FALSE) button.
42 $this->drupalGet($path . '/s');
43 $this->getSession()->getDriver()->submitForm('//form[@id="' . $form_html_id . '"]');
44 $assert_session->pageTextContains('The clicked button is button1.');
45 $assert_session->pageTextContains('Submit handler for form_test_clicked_button executed.');
47 $this->drupalGet($path . '/s/s');
48 $this->getSession()->getDriver()->submitForm('//form[@id="' . $form_html_id . '"]');
49 $assert_session->pageTextContains('The clicked button is button1.');
50 $assert_session->pageTextContains('Submit handler for form_test_clicked_button executed.');
52 $this->drupalGet($path . '/rs/s');
53 $this->getSession()->getDriver()->submitForm('//form[@id="' . $form_html_id . '"]');
54 $assert_session->pageTextContains('The clicked button is button2.');
55 $assert_session->pageTextContains('Submit handler for form_test_clicked_button executed.');
57 // Ensure submitting a form with buttons of different types results in the
58 // triggering element being set to the first button, regardless of type. For
59 // the FAPI 'button' type, this should result in the submit handler not
60 // executing. The types are 's'(ubmit), 'b'(utton), and 'i'(mage_button).
61 $this->drupalGet($path . '/s/b/i');
62 $this->getSession()->getDriver()->submitForm('//form[@id="' . $form_html_id . '"]');
63 $assert_session->pageTextContains('The clicked button is button1.');
64 $assert_session->pageTextContains('Submit handler for form_test_clicked_button executed.');
66 $this->drupalGet($path . '/b/s/i');
67 $this->getSession()->getDriver()->submitForm('//form[@id="' . $form_html_id . '"]');
68 $assert_session->pageTextContains('The clicked button is button1.');
69 $assert_session->pageTextNotContains('Submit handler for form_test_clicked_button executed.');
71 $this->drupalGet($path . '/i/s/b');
72 $this->getSession()->getDriver()->submitForm('//form[@id="' . $form_html_id . '"]');
73 $assert_session->pageTextContains('The clicked button is button1.');
74 $assert_session->pageTextContains('Submit handler for form_test_clicked_button executed.');
78 * Tests attempts to bypass access control.
80 * Test that the triggering element does not get set to a button with
83 public function testAttemptAccessControlBypass() {
84 $path = 'form-test/clicked-button';
85 $form_html_id = 'form-test-clicked-button';
87 // Retrieve a form where 'button1' has #access=FALSE and 'button2' doesn't.
88 $this->drupalGet($path . '/rs/s');
90 // Submit the form with 'button1=button1' in the POST data, which someone
91 // trying to get around security safeguards could easily do. We have to do
92 // a little trickery here, to work around the safeguards in drupalPostForm()
93 // by renaming the text field and value that is in the form to 'button1',
94 // we can get the data we want into \Drupal::request()->request.
95 $page = $this->getSession()->getPage();
96 $input = $page->find('css', 'input[name="text"]');
97 $this->assertNotNull($input, 'text input located.');
99 $input->setValue('name', 'button1');
100 $input->setValue('value', 'button1');
101 $this->xpath('//form[@id="' . $form_html_id . '"]//input[@type="submit"]')[0]->click();
103 // Ensure that the triggering element was not set to the restricted button.
104 // Do this with both a negative and positive assertion, because negative
105 // assertions alone can be brittle. See testNoButtonInfoInPost() for why the
106 // triggering element gets set to 'button2'.
107 $this->assertSession()->pageTextNotContains('The clicked button is button1.');
108 $this->assertSession()->pageTextContains('The clicked button is button2.');