Coder Social home page Coder Social logo

Comments (4)

cordoval avatar cordoval commented on May 20, 2024

@richardmiller, I have the same problem

looking at this called from here

<?php
    /**
     * Selects option from select field with specified locator.
     *
     * @param   string  $locator    input id, name or label
     *
     * @throws  Behat\Mink\Exception\ElementNotFoundException
     */
    public function selectFieldOption($locator, $value)
    {
        $field = $this->findField($locator);

        if (null === $field) {
            throw new ElementNotFoundException(
                $this->getSession(), 'form field', 'id|name|label|value', $locator
            );
        }

        $field->selectOption($value);
    }

The selectOption is:

<?php
    /**
     * Selects current node specified option if it's a select field.
     *
     * @param   string  $option
     */
    public function selectOption($option)
    {
        $this->getSession()->getDriver()->selectOption($this->getXpath(), $option);
    }

The selectOption method at this level depends on the driver implementation:

<?php
vendor/behat/mink/src/Behat/Mink/Driver/DriverInterface.php
225:    function selectOption($xpath, $value);

vendor/behat/mink/src/Behat/Mink/Driver/GoutteDriver.php
313:     * @see     Behat\Mink\Driver\DriverInterface::selectOption()
315:    public function selectOption($xpath, $value)

vendor/behat/mink/src/Behat/Mink/Driver/SahiDriver.php
366:     * @see     Behat\Mink\Driver\DriverInterface::selectOption()
368:    public function selectOption($xpath, $value)

vendor/behat/mink/src/Behat/Mink/Driver/ZombieDriver.php
454:     * @see     Behat\Mink\Driver\DriverInterface::selectOption()
456:    public function selectOption($xpath, $value)

vendor/behat/mink/src/Behat/Mink/Behat/Context/BaseMinkContext.php
204:    public function selectOption($select, $option)

If we take sahi for instance we find this:

<?php
    /**
     * @see     Behat\Mink\Driver\DriverInterface::selectOption()
     */
    public function selectOption($xpath, $value)
    {
        $type = $this->getAttribute($xpath, 'type');

        if ('radio' === $type) {
            $this->selectRadioOption($xpath, $value);
        } else {
            $this->client->findByXPath($this->prepareXPath($xpath))->choose($value);
        }
    }

And most likely down to the bottom at this level all is implementation dependent.

Therefore the only place where we can swap is up the chain,

<?php
    /**
     * Selects option from select field with specified locator.
     *
     * @param   string  $locator    input id, name or label
     *
     * @throws  Behat\Mink\Exception\ElementNotFoundException
     */
    public function selectFieldOption($locator, $value)
    {
        $field = $this->findField($locator);

        if (null === $field) {
            throw new ElementNotFoundException(
                $this->getSession(), 'form field', 'id|name|label|value', $locator
            );
        }

        //  here we transform $value _if_ $value is the contents of the <option value="x">y</option> tags so $value == y
        //  into $value == x

        $field->selectOption($value);
    }

In order to rule out the ambiguity of this situation we will create another method on the base mink context class, since it seems it keeps BC and also simplifies the code.

<?php
    /**
     * Selects option label in select field with specified id|name|label|value.
     *
     * @When /^(?:|I )select label "(?P<optionLabel>(?:[^"]|\\")*)" from "(?P<select>(?:[^"]|\\")*)"$/
     */
    public function selectOption($select, $optionLabel)
    {
        $select = str_replace('\\"', '"', $select);
        $option = str_replace('\\"', '"', $optionLabel);
        $this->getSession()->getPage()->selectFieldOptionLabel($select, $optionLabel);
    }

And we write selectFieldOptionLabel as:

<?php
    /**
     * Selects option from select field with specified locator.
     *
     * @param   string  $locator    input id, name or label
     * @param   string  $optionLabel    label between option tags       
     * @throws  Behat\Mink\Exception\ElementNotFoundException
     */
    public function selectFieldOptionLabel($locator, $optionLabel)
    {
        $field = $this->findField($locator);

        if (null === $field) {
            throw new ElementNotFoundException(
                $this->getSession(), 'form field', 'id|name|label|value', $locator
            );
        }

        // get $value from $optionLabel
        $value = $field->fromLabelToValue($optionLabel);

        $field->selectOption($value);
    }

@richardmiller there is an optgroup or option named selectors on mink documentation here, in addition to this there is support for nested traversing ... thus we can reuse $field as below

perhaps we can use those to do something like:

<?php
 $optionItems = $field->findAll???();
 foreach $optionItems as $item {
    if($item->getText() == $optionLabel) {
       $valueOption = $item->getValue();
    }
 }

from mink.

cordoval avatar cordoval commented on May 20, 2024

@richardmiller

see below, can you please help?

<?php
 /**
     * Selects option from select field with specified locator.
     *
     * @param   string  $locator    input id, name or label
     *
     * @throws  Behat\Mink\Exception\ElementNotFoundException
     */
    public function selectFieldOption($locator, $value)
    {
        /* @var \Behat\Mink\Element\NodeElement $field */
        $field = $this->findField($locator);

        if (null === $field) {
            throw new ElementNotFoundException(
                $this->getSession(), 'form field', 'id|name|label|value', $locator
            );
        }

        /* @var \Behat\Mink\Selector\SelectorsHandler $handler */
        $handler = $this->getSession()->getSelectorsHandler();

        $optionElements = $this->findAll('named', array(
            'option', $handler->selectorToXpath('css', 'option')
        ));

        /* @var \Behat\Mink\Element\NodeElement $optionElements */
        foreach ($optionElements as $item) {
            if((string)$item->getText() == $value) {
                //$actualValue = $item->getValue();
                var_export('1');
            }
        }
        $field->selectOption($actualValue);
    }

When I uncomment the //$actualValue = $item->getValue() all stops working

we are almost there but there seems to be recursion I don't understand, can you hint me please?

from mink.

mintbridge avatar mintbridge commented on May 20, 2024

Im not sure this is quite working properly, as it always returns the first option element in the select
If you change:
Behat@173c49d#L1R316
from $select->selectOption('ten'); to be $select->selectOption('thirty'); then i think the unit test will fail

from mink.

mintbridge avatar mintbridge commented on May 20, 2024

It also throws an exception would you try to select an option that contains a space e.g.
When I select "Test 1" from "testselect"

from mink.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.