Skip to main content
Drupal API
User account menu
  • Log in

Breadcrumb

  1. Drupal Core 11.1.x
  2. Selenium2Driver.php

function Selenium2Driver::setValue

Overrides CoreDriver::setValue

File

vendor/lullabot/mink-selenium2-driver/src/Selenium2Driver.php, line 685

Class

Selenium2Driver
Selenium2 driver.

Namespace

Behat\Mink\Driver

Code

public function setValue(string $xpath, $value) {
    $element = $this->findElement($xpath);
    $elementName = strtolower($element->name());
    if ('select' === $elementName) {
        if (is_array($value)) {
            $this->deselectAllOptions($element);
            foreach ($value as $option) {
                $this->selectOptionOnElement($element, $option, true);
            }
            return;
        }
        if (\is_bool($value)) {
            throw new DriverException('Boolean values cannot be used for a select element.');
        }
        $this->selectOptionOnElement($element, $value);
        return;
    }
    if ('input' === $elementName) {
        $elementType = strtolower($element->attribute('type') ?: '');
        if (in_array($elementType, array(
            'submit',
            'image',
            'button',
            'reset',
        ))) {
            throw new DriverException(sprintf('Impossible to set value an element with XPath "%s" as it is not a select, textarea or textbox', $xpath));
        }
        if ('checkbox' === $elementType) {
            if ($element->selected() xor (bool) $value) {
                $this->clickOnElement($element);
            }
            return;
        }
        if ('radio' === $elementType) {
            if (!\is_string($value)) {
                throw new DriverException('Only string values can be used for a radio input.');
            }
            $this->selectRadioValue($element, $value);
            return;
        }
        if ('file' === $elementType) {
            if (!\is_string($value)) {
                throw new DriverException('Only string values can be used for a file input.');
            }
            if ($this->isW3C()) {
                $element->postValue(array(
                    'text' => $value,
                ));
            }
            else {
                $element->postValue(array(
                    'value' => array(
                        $value,
                    ),
                ));
            }
            return;
        }
    }
    if (!\is_string($value)) {
        throw new DriverException(sprintf('Only string values can be used for a %s element.', $elementName));
    }
    $value = strval($value);
    if (in_array($elementName, array(
        'input',
        'textarea',
    ))) {
        if ($this->isW3C()) {
            $existingValueLength = strlen($element->property('value'));
        }
        else {
            $existingValueLength = strlen($element->attribute('value'));
        }
        $value = str_repeat(Key::BACKSPACE . Key::DELETE, $existingValueLength) . $value;
    }
    if ($this->isW3C()) {
        $element->postValue(array(
            'text' => $value,
        ));
    }
    else {
        $element->postValue(array(
            'value' => array(
                $value,
            ),
        ));
    }
    // Remove the focus from the element if the field still has focus in
    // order to trigger the change event. By doing this instead of simply
    // triggering the change event for the given xpath we ensure that the
    // change event will not be triggered twice for the same element if it
    // has lost focus in the meanwhile. If the element has lost focus
    // already then there is nothing to do as this will already have caused
    // the triggering of the change event for that element.
    $script = <<<JS
var node = {{ELEMENT}};
if (document.activeElement === node) {
  document.activeElement.blur();
}
JS;
    // Cover case, when an element was removed from DOM after its value was
    // changed (e.g. by a JavaScript of a SPA) and therefore can't be focused.
    try {
        $this->executeJsOnElement($element, $script);
    } catch (StaleElementReference $e) {
        // Do nothing because an element was already removed and therefore
        // blurring is not needed.
    }
}
RSS feed
Powered by Drupal