View source  
  <?php
namespace Drupal\Tests\system\Functional\Form;
use Drupal\form_test\Form\FormTestLabelForm;
use Drupal\Tests\BrowserTestBase;
class ElementsLabelsTest extends BrowserTestBase {
  
  protected static $modules = [
    'form_test',
  ];
  
  protected $defaultTheme = 'stark';
  
  public function testFormLabels() {
    $this
      ->drupalGet('form_test/form-labels');
    
    $this
      ->assertSession()
      ->elementExists('xpath', '//input[@id="edit-form-checkboxes-test-third-checkbox"]/following-sibling::label[@for="edit-form-checkboxes-test-third-checkbox" and @class="option"]');
    
    $this
      ->assertSession()
      ->elementExists('xpath', '//input[@id="edit-form-checkboxes-test-0"]/following-sibling::label[@for="edit-form-checkboxes-test-0" and @class="option"]');
    $this
      ->assertSession()
      ->elementExists('xpath', '//input[@id="edit-form-radios-test-second-radio"]/following-sibling::label[@for="edit-form-radios-test-second-radio" and @class="option"]');
    
    $this
      ->assertSession()
      ->elementExists('xpath', '//input[@id="edit-form-radios-test-0"]/following-sibling::label[@for="edit-form-radios-test-0" and @class="option"]');
    
    $this
      ->assertSession()
      ->elementExists('xpath', '//input[@id="edit-form-checkbox-test"]/following-sibling::label[@for="edit-form-checkbox-test" and @class="option"]');
    
    $this
      ->assertSession()
      ->elementExists('xpath', '//label[@for="edit-form-textfield-test-title-and-required" and @class="js-form-required form-required"]/following-sibling::input[@id="edit-form-textfield-test-title-and-required"]');
    
    $this
      ->assertSession()
      ->elementExists('xpath', '//input[@id="edit-form-textfield-test-no-title-required"]/preceding-sibling::label[@for="edit-form-textfield-test-no-title-required" and @class="js-form-required form-required"]');
    
    $this
      ->assertSession()
      ->elementExists('xpath', '//input[@id="edit-form-textfield-test-title-invisible"]/preceding-sibling::label[@for="edit-form-textfield-test-title-invisible" and @class="visually-hidden"]');
    
    $this
      ->assertSession()
      ->elementNotExists('xpath', '//input[@id="edit-form-textfield-test-title"]/preceding-sibling::span[@class="js-form-required form-required"]');
    
    $this
      ->assertSession()
      ->elementExists('xpath', '//input[@id="edit-form-textfield-test-title-after"]/following-sibling::label[@for="edit-form-textfield-test-title-after" and @class="option"]');
    
    $this
      ->assertSession()
      ->elementNotExists('xpath', '//label[@for="edit-form-textfield-test-title-no-show"]');
    
    $this
      ->assertSession()
      ->elementExists('xpath', '//div[contains(@class, "js-form-item-form-textfield-test-title-invisible") and contains(@class, "form-no-label")]');
    
    $this
      ->assertSession()
      ->elementExists('xpath', '//span[@class="field-prefix"]/following-sibling::div[@id="edit-form-radios-test"]');
    $this
      ->assertSession()
      ->elementExists('xpath', '//span[@class="field-suffix"]/preceding-sibling::div[@id="edit-form-radios-test"]');
    
    $this
      ->assertSession()
      ->elementExists('xpath', '//div[@id="form-test-textfield-title-prefix"]/following-sibling::div[contains(@class, \'js-form-item-form-textfield-test-title\')]');
    $this
      ->assertSession()
      ->elementExists('xpath', '//div[@id="form-test-textfield-title-suffix"]/preceding-sibling::div[contains(@class, \'js-form-item-form-textfield-test-title\')]');
    
    $this
      ->assertSession()
      ->elementAttributeContains('css', '#edit-form-checkboxes-title-attribute', 'title', 'Checkboxes test (Required)');
    $this
      ->assertSession()
      ->elementAttributeContains('css', '#edit-form-radios-title-attribute', 'title', 'Radios test (Required)');
    
    $this
      ->assertSession()
      ->elementExists('xpath', '//fieldset[@id="edit-form-checkboxes-title-invisible--wrapper"]/legend/span[contains(@class, "visually-hidden")]');
    
    $this
      ->assertSession()
      ->elementExists('xpath', '//fieldset[@id="edit-form-radios-title-invisible--wrapper"]/legend/span[contains(@class, "visually-hidden")]');
  }
  
  public function testTitleEscaping() {
    $this
      ->drupalGet('form_test/form-labels');
    foreach (FormTestLabelForm::$typesWithTitle as $type) {
      $this
        ->assertSession()
        ->responseContains("{$type} alert('XSS') is XSS filtered!");
      $this
        ->assertSession()
        ->responseNotContains("{$type} <script>alert('XSS')</script> is XSS filtered!");
    }
  }
  
  public function testFormDescriptions() {
    $this
      ->drupalGet('form_test/form-descriptions');
    
    $field_id = 'edit-form-textfield-test-description-after';
    $description_id = $field_id . '--description';
    
    $this
      ->assertSession()
      ->elementExists('xpath', '//input[@id="' . $field_id . '" and @aria-describedby="' . $description_id . '"]/following-sibling::div[@id="' . $description_id . '"]');
    
    $field_id = 'edit-form-textfield-test-description-before';
    $description_id = $field_id . '--description';
    
    $this
      ->assertSession()
      ->elementExists('xpath', '//input[@id="' . $field_id . '" and @aria-describedby="' . $description_id . '"]/preceding-sibling::div[@id="' . $description_id . '"]');
    
    $field_id = 'edit-form-textfield-test-description-invisible';
    $description_id = $field_id . '--description';
    
    $this
      ->assertSession()
      ->elementExists('xpath', '//input[@id="' . $field_id . '" and @aria-describedby="' . $description_id . '"]/following-sibling::div[contains(@class, "visually-hidden")]');
  }
  
  public function testFormsInThemeLessEnvironments() {
    $form = $this
      ->getFormWithLimitedProperties();
    $render_service = $this->container
      ->get('renderer');
    
    $render_service
      ->renderPlain($form);
  }
  
  protected function getFormWithLimitedProperties() {
    $form = [];
    $form['fieldset'] = [
      '#type' => 'fieldset',
      '#title' => 'Fieldset',
    ];
    return $form;
  }
}