How do we check Twitter Bootstrap radio buttons using Laravel Dusk?

Viewed 3300

According to twitter bootstrap, this is how we do a radio:

<div class="radio">
  <label>
    <input type="radio" name="optionsRadios" id="optionsRadios1" value="option1" checked>
    Option one is this and that&mdash;be sure to include why it's great
  </label>
</div>

And this is my code:

$browser->click('#menu-reports')
        ->waitForText('Users')
        ->click('#menu-reports-users')
        ->radio('sitesActive', '2')
        ->radio('includeDisabled', '2')
        ->radio('includeNonCertifiable', '2')
        ->press('Apply')
        ->waitForText('Showing 0 to 0 of 0 entries')
;

With the input inside the label tag. But the problem is that Dusk (actually Facebook Webdriver) is not able to find it this way. It keeps raising:

Facebook\WebDriver\Exception\ElementNotVisibleException: element not visible

To make it work I have put the input outside the label, but then, of course, the boostrap radio does not show as it should anymore.

<div class="radio">
  <input type="radio" name="optionsRadios" id="optionsRadios1" value="option1" checked>
  <label>
    Option one is this and that&mdash;be sure to include why it's great
  </label>
</div>

Does not work using IDs either:

Not even setting an ID to the input:

<input 
   type="radio" 
   name="sitesActive" 
   id="sitesActive3" 
   value="2"
>

And trying to select it this way:

->radio('#sitesActive3', '2')

The problem is that Dusk (Webdriver) cannot even see the element in the page, as this simple like fails the exact same way:

$browser->waitFor('#sitesActive3');

Resulting in:

Facebook\WebDriver\Exception\TimeOutException: Waited 5 seconds for selector [#sitesActive3].

And that happens every time I have a form with an input with a label surrounding it, if I take the input out of the label, it works. But that's not as simple with radios, as it was with some other inputs, radios.

This is a properly coded radio:

image

This is a radio with the input outside the label tag:

image

So, how are you doing this?

4 Answers

simplest way is to click on the parent

$el = $this->resolver->resolveForRadioSelection($field, $value);
$el = $el->findElement(WebDriverBy::xpath(".."));
$el->click();

Since the radio is not visible dusk cannot click on it

You may create a trait like the following if you are using bootstrap in your project

trait BootstrapInteraction
{
    /**
     * Undocumented variable
     * @var \Laravel\Dusk\ElementResolver $resolver
     */
    public   $resolver;
    public function radioB($field, $value)
    {
        /**
         * @var RemoteWebElement $el
         */
        $radio = $this->resolver->resolveForRadioSelection($field, $value);
        // click on parent
        $el = $radio->findElement(WebDriverBy::xpath(".."));
        $el->click();
        // if not selected click on label 
        if (!$radio->isSelected()) {
            $el = $el->findElement(WebDriverBy::cssSelector("label"));
            $el->click();
        }

        PHPUnit::assertTrue(
            $radio->isSelected(),
            "Not able to select Radio [{$field}] within value [{$value}]."
        ); 

        return $this;
    }

The Dusk docs say:

To "select" a radio button option, you may use the radio method. Like many other input related methods, a full CSS selector is not required. If an exact selector match can't be found, Dusk will search for a radio with matching name and value attributes: $browser->radio('version', 'php7');

In my case, Dusk was working fine for most of my radio buttons, but it would not work for:

->radio('Field728', 'Know it\'s what anyone committed to this dream would do if she found a great program that features a proven process and supportive community')

I also tried using double-quotes, but that didn't work either. (Maybe the value is too long? I don't know.)

So instead I did this:

->radio('#Field728_0', true)//this is the specific ID of the first radio button of this group

Related