diff --git a/core/modules/simpletest/src/AssertContentTrait.php b/core/modules/simpletest/src/AssertContentTrait.php index 54dba00..1fa736e 100644 --- a/core/modules/simpletest/src/AssertContentTrait.php +++ b/core/modules/simpletest/src/AssertContentTrait.php @@ -1090,8 +1090,8 @@ protected function assertNoFieldById($id, $value = '', $message = '', $group = ' /** * Asserts that a checkbox field in the current page is checked. * - * @param string $id - * ID of field to assert. + * @param string $drupal_selector + * Drupal data selector of field to assert. * @param string $message * (optional) A message to display with the assertion. Do not translate * messages: use format_string() to embed variables in the message text, not @@ -1105,15 +1105,15 @@ protected function assertNoFieldById($id, $value = '', $message = '', $group = ' * @return bool * TRUE on pass, FALSE on fail. */ - protected function assertFieldChecked($id, $message = '', $group = 'Browser') { - $elements = $this->xpath('//input[@id=:id]', array(':id' => $id)); - return $this->assertTrue(isset($elements[0]) && !empty($elements[0]['checked']), $message ? $message : SafeMarkup::format('Checkbox field @id is checked.', array('@id' => $id)), $group); + protected function assertFieldChecked($drupal_selector, $message = '', $group = 'Browser') { + $elements = $this->xpath('//input[@drupal-data-selector=:drupal_data_selector]', array(':drupal_data_selector' => $drupal_selector)); + return $this->assertTrue(isset($elements[0]) && !empty($elements[0]['checked']), $message ? $message : SafeMarkup::format('Checkbox field @id is checked.', array('@id' => $drupal_selector)), $group); } /** * Asserts that a checkbox field in the current page is not checked. * - * @param string $id + * @param string $drupal_selector * ID of field to assert. * @param string $message * (optional) A message to display with the assertion. Do not translate @@ -1128,15 +1128,15 @@ protected function assertFieldChecked($id, $message = '', $group = 'Browser') { * @return bool * TRUE on pass, FALSE on fail. */ - protected function assertNoFieldChecked($id, $message = '', $group = 'Browser') { - $elements = $this->xpath('//input[@id=:id]', array(':id' => $id)); - return $this->assertTrue(isset($elements[0]) && empty($elements[0]['checked']), $message ? $message : SafeMarkup::format('Checkbox field @id is not checked.', array('@id' => $id)), $group); + protected function assertNoFieldChecked($drupal_selector, $message = '', $group = 'Browser') { + $elements = $this->xpath('//input[@drupal-data-selector=:drupal_data_selector]', array(':drupal_data_selector' => $drupal_selector)); + return $this->assertTrue(isset($elements[0]) && empty($elements[0]['checked']), $message ? $message : SafeMarkup::format('Checkbox field @id is not checked.', array('@id' => $drupal_selector)), $group); } /** * Asserts that a select option in the current page exists. * - * @param string $id + * @param string $drupal_selector * ID of select field to assert. * @param string $option * Option to assert. @@ -1153,15 +1153,15 @@ protected function assertNoFieldChecked($id, $message = '', $group = 'Browser') * @return bool * TRUE on pass, FALSE on fail. */ - protected function assertOption($id, $option, $message = '', $group = 'Browser') { - $options = $this->xpath('//select[@id=:id]//option[@value=:option]', array(':id' => $id, ':option' => $option)); - return $this->assertTrue(isset($options[0]), $message ? $message : SafeMarkup::format('Option @option for field @id exists.', array('@option' => $option, '@id' => $id)), $group); + protected function assertOption($drupal_selector, $option, $message = '', $group = 'Browser') { + $options = $this->xpath('//select[@drupal-data-selector=:drupal_data_selector]//option[@value=:option]', array(':drupal_data_selector' => $drupal_selector, ':option' => $option)); + return $this->assertTrue(isset($options[0]), $message ? $message : SafeMarkup::format('Option @option for field @id exists.', array('@option' => $option, '@id' => $drupal_selector)), $group); } /** * Asserts that a select option in the current page does not exist. * - * @param string $id + * @param string $drupal_selector * ID of select field to assert. * @param string $option * Option to assert. @@ -1178,16 +1178,16 @@ protected function assertOption($id, $option, $message = '', $group = 'Browser') * @return bool * TRUE on pass, FALSE on fail. */ - protected function assertNoOption($id, $option, $message = '', $group = 'Browser') { - $selects = $this->xpath('//select[@id=:id]', array(':id' => $id)); - $options = $this->xpath('//select[@id=:id]//option[@value=:option]', array(':id' => $id, ':option' => $option)); - return $this->assertTrue(isset($selects[0]) && !isset($options[0]), $message ? $message : SafeMarkup::format('Option @option for field @id does not exist.', array('@option' => $option, '@id' => $id)), $group); + protected function assertNoOption($drupal_selector, $option, $message = '', $group = 'Browser') { + $selects = $this->xpath('//select[@drupal-data-selector=:drupal_data_selector]', array(':id' => $drupal_selector)); + $options = $this->xpath('//select[@drupal-data-selector=:drupal_data_selector]//option[@value=:option]', array(':drupal_data_selector' => $drupal_selector, ':option' => $option)); + return $this->assertTrue(isset($selects[0]) && !isset($options[0]), $message ? $message : SafeMarkup::format('Option @option for field @id does not exist.', array('@option' => $option, '@id' => $drupal_selector)), $group); } /** * Asserts that a select option in the current page is checked. * - * @param string $id + * @param string $drupal_selector * ID of select field to assert. * @param string $option * Option to assert. @@ -1206,15 +1206,15 @@ protected function assertNoOption($id, $option, $message = '', $group = 'Browser * * @todo $id is unusable. Replace with $name. */ - protected function assertOptionSelected($id, $option, $message = '', $group = 'Browser') { - $elements = $this->xpath('//select[@id=:id]//option[@value=:option]', array(':id' => $id, ':option' => $option)); - return $this->assertTrue(isset($elements[0]) && !empty($elements[0]['selected']), $message ? $message : SafeMarkup::format('Option @option for field @id is selected.', array('@option' => $option, '@id' => $id)), $group); + protected function assertOptionSelected($drupal_selector, $option, $message = '', $group = 'Browser') { + $elements = $this->xpath('//select[@drupal-data-selector=:drupal_data_selector]//option[@value=:option]', array(':drupal_data_selector' => $drupal_selector, ':option' => $option)); + return $this->assertTrue(isset($elements[0]) && !empty($elements[0]['selected']), $message ? $message : SafeMarkup::format('Option @option for field @id is selected.', array('@option' => $option, '@id' => $drupal_selector)), $group); } /** * Asserts that a select option in the current page is not checked. * - * @param string $id + * @param string $drupal_selector * ID of select field to assert. * @param string $option * Option to assert. @@ -1231,16 +1231,16 @@ protected function assertOptionSelected($id, $option, $message = '', $group = 'B * @return bool * TRUE on pass, FALSE on fail. */ - protected function assertNoOptionSelected($id, $option, $message = '', $group = 'Browser') { - $elements = $this->xpath('//select[@id=:id]//option[@value=:option]', array(':id' => $id, ':option' => $option)); - return $this->assertTrue(isset($elements[0]) && empty($elements[0]['selected']), $message ? $message : SafeMarkup::format('Option @option for field @id is not selected.', array('@option' => $option, '@id' => $id)), $group); + protected function assertNoOptionSelected($drupal_selector, $option, $message = '', $group = 'Browser') { + $elements = $this->xpath('//select[@drupal-data-selector=:drupal_data_selector]//option[@value=:option]', array(':drupal_data_selector' => $drupal_selector, ':option' => $option)); + return $this->assertTrue(isset($elements[0]) && empty($elements[0]['selected']), $message ? $message : SafeMarkup::format('Option @option for field @id is not selected.', array('@option' => $option, '@id' => $drupal_selector)), $group); } /** - * Asserts that a field exists with the given name or ID. + * Asserts that a field exists with the given name or ID or drupal-selector. * * @param string $field - * Name or ID of field to assert. + * Name or ID or data-drupal-selector of field to assert. * @param string $message * (optional) A message to display with the assertion. Do not translate * messages: use format_string() to embed variables in the message text, not @@ -1255,14 +1255,14 @@ protected function assertNoOptionSelected($id, $option, $message = '', $group = * TRUE on pass, FALSE on fail. */ protected function assertField($field, $message = '', $group = 'Other') { - return $this->assertFieldByXPath($this->constructFieldXpath('name', $field) . '|' . $this->constructFieldXpath('id', $field), NULL, $message, $group); + return $this->assertFieldByXPath($this->constructFieldXpath('name', $field) . '|' . $this->constructFieldXpath('id', $field) . '|' . $this->constructFieldXpath('data-drupal-selector', $field), NULL, $message, $group); } /** - * Asserts that a field does not exist with the given name or ID. + * Asserts that a field does not exist with the given name or ID or data-drupal-selector. * * @param string $field - * Name or ID of field to assert. + * Name or ID or data-drupal-selector of field to assert. * @param string $message * (optional) A message to display with the assertion. Do not translate * messages: use format_string() to embed variables in the message text, not @@ -1277,7 +1277,7 @@ protected function assertField($field, $message = '', $group = 'Other') { * TRUE on pass, FALSE on fail. */ protected function assertNoField($field, $message = '', $group = 'Other') { - return $this->assertNoFieldByXPath($this->constructFieldXpath('name', $field) . '|' . $this->constructFieldXpath('id', $field), NULL, $message, $group); + return $this->assertNoFieldByXPath($this->constructFieldXpath('name', $field) . '|' . $this->constructFieldXpath('id', $field) . '|' . $this->constructFieldXpath('data-drupal-selector', $field), NULL, $message, $group); } /** diff --git a/core/modules/simpletest/src/WebTestBase.php b/core/modules/simpletest/src/WebTestBase.php index c8cced7..eef5241 100644 --- a/core/modules/simpletest/src/WebTestBase.php +++ b/core/modules/simpletest/src/WebTestBase.php @@ -1505,13 +1505,10 @@ protected function drupalGetAjax($path, array $options = array(), array $headers * @param $headers * An array containing additional HTTP request headers, each formatted as * "name: value". - * @param $form_html_id - * (optional) HTML ID of the form to be submitted. On some pages + * @param $xpath + * (optional) The xpath selector of the form to be submitted. On some pages * there are many identical forms, so just using the value of the submit * button is not enough. For example: 'trigger-node-presave-assign-form'. - * Note that this is not the Drupal $form_id, but rather the HTML ID of the - * form, which is typically the same thing but with hyphens replacing the - * underscores. * @param $extra_post * (optional) A string of additional data to append to the POST submission. * This can be used to add POST data for which there are no HTML fields, as @@ -1519,7 +1516,7 @@ protected function drupalGetAjax($path, array $options = array(), array $headers * POST data, so it must already be urlencoded and contain a leading "&" * (e.g., "&extra_var1=hello+world&extra_var2=you%26me"). */ - protected function drupalPostForm($path, $edit, $submit, array $options = array(), array $headers = array(), $form_html_id = NULL, $extra_post = NULL) { + protected function drupalPostForm($path, $edit, $submit, array $options = array(), array $headers = array(), $xpath = '//form', $extra_post = NULL) { $submit_matches = FALSE; $ajax = is_array($submit); if (isset($path)) { @@ -1529,10 +1526,6 @@ protected function drupalPostForm($path, $edit, $submit, array $options = array( if ($this->parse()) { $edit_save = $edit; // Let's iterate over all the forms. - $xpath = "//form"; - if (!empty($form_html_id)) { - $xpath .= "[@id='" . $form_html_id . "']"; - } $forms = $this->xpath($xpath); foreach ($forms as $form) { // We try to set the fields of this form as specified in $edit. @@ -1635,11 +1628,10 @@ protected function drupalPostForm($path, $edit, $submit, array $options = array( * @param $headers * (optional) An array containing additional HTTP request headers, each * formatted as "name: value". Forwarded to drupalPostForm(). - * @param $form_html_id - * (optional) HTML ID of the form to be submitted, use when there is more - * than one identical form on the same page and the value of the triggering - * element is not enough to identify the form. Note this is not the Drupal - * ID of the form but rather the HTML ID of the form. + * @param $form_xpath + * (optional) The xpath selector of the form to be submitted. On some pages + * there are many identical forms, so just using the value of the submit + * button is not enough. For example: 'trigger-node-presave-assign-form'. * @param $ajax_settings * (optional) An array of Ajax settings which if specified will be used in * place of the Ajax settings of the triggering element. @@ -1651,7 +1643,7 @@ protected function drupalPostForm($path, $edit, $submit, array $options = array( * @see drupalProcessAjaxResponse() * @see ajax.js */ - protected function drupalPostAjaxForm($path, $edit, $triggering_element, $ajax_path = NULL, array $options = array(), array $headers = array(), $form_html_id = NULL, $ajax_settings = NULL) { + protected function drupalPostAjaxForm($path, $edit, $triggering_element, $ajax_path = NULL, array $options = array(), array $headers = array(), $form_xpath = NULL, $ajax_settings = NULL) { // Get the content of the initial page prior to calling drupalPostForm(), // since drupalPostForm() replaces $this->content. @@ -1679,8 +1671,8 @@ protected function drupalPostAjaxForm($path, $edit, $triggering_element, $ajax_p else { $xpath = '//*[@name="' . $triggering_element . '"]'; } - if (isset($form_html_id)) { - $xpath = '//form[@id="' . $form_html_id . '"]' . $xpath; + if (isset($form_xpath)) { + $xpath = '//' . $form_xpath . $xpath; } $element = $this->xpath($xpath); $element_id = (string) $element[0]['id']; @@ -1724,7 +1716,7 @@ protected function drupalPostAjaxForm($path, $edit, $triggering_element, $ajax_p $ajax_path = $this->container->get('unrouted_url_assembler')->assemble('base://' . $ajax_path, $options); // Submit the POST request. - $return = Json::decode($this->drupalPostForm(NULL, $edit, array('path' => $ajax_path, 'triggering_element' => $triggering_element), $options, $headers, $form_html_id, $extra_post)); + $return = Json::decode($this->drupalPostForm(NULL, $edit, array('path' => $ajax_path, 'triggering_element' => $triggering_element), $options, $headers, $form_xpath, $extra_post)); // Change the page content by applying the returned commands. if (!empty($ajax_settings) && !empty($return)) { diff --git a/core/modules/system/src/Tests/Form/RebuildTest.php b/core/modules/system/src/Tests/Form/RebuildTest.php index e993b49..272338b 100644 --- a/core/modules/system/src/Tests/Form/RebuildTest.php +++ b/core/modules/system/src/Tests/Form/RebuildTest.php @@ -96,7 +96,7 @@ function testPreserveFormActionAfterAJAX() { // submission and verify it worked by ensuring the updated page has two text // field items in the field for which we just added an item. $this->drupalGet('node/add/page'); - $this->drupalPostAjaxForm(NULL, array(), array('field_ajax_test_add_more' => t('Add another item')), 'system/ajax', array(), array(), 'node-page-form'); + $this->drupalPostAjaxForm(NULL, array(), array('field_ajax_test_add_more' => t('Add another item')), 'system/ajax', array(), array(), '/form[@data-drupal-selector=node-page-form]'); $this->assert(count($this->xpath('//div[contains(@class, "field-name-field-ajax-test")]//input[@type="text"]')) == 2, 'AJAX submission succeeded.'); // Submit the form with the non-Ajax "Save" button, leaving the title field