4

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?

Antonio Carlos Ribeiro
  • 86,191
  • 22
  • 213
  • 204

4 Answers4

4

My form has a radio button. This how I checked it.

userCreate.blade.php

<div class="row">
    <div class="col-md-12">
        <div class="form-group">
            <label>Gender</label>
            <div>
                <label class="radio-inline">
                    <input type="radio" id="gender" name="gender" value="m">Male
                </label>
                <label class="radio-inline">
                    <input type="radio" id="gender" name="gender" value="f">Female
                </label>
            </div>
        </div>
    </div>
</div>

CreateUserTest.php

class CreateUserTest extends DuskTestCase
{

    public function  testCreateForm()
    {
        $this->browse(function (Browser $browser) {
            $browser->visit('/user/create')
                ->radio('#gender', 'm')
                ->click('button[type="submit"]')
                ->assertSee('Successfully created user.');
        });
    }
}

This works for me. I think this will help you.

Janaka Pushpakumara
  • 4,769
  • 5
  • 29
  • 34
  • 1
    This seems incorrect because you've set `id="gender"` to multiple elements on the same page, which breaks the HTML rule that `id` must be unique. – Ryan Dec 04 '19 at 23:09
  • Should not have multiple id attributes – digout Jan 07 '21 at 12:06
2

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;
    }
Pascal
  • 2,377
  • 3
  • 25
  • 40
  • This is the best answer imho. The $el = $browser etc. worked like a charm, straight out the box. However, @Pascal, i couldn't implement your suggested trait method. I created the Trait and added use Trait inside file and class. I access the Dusk browser instance via: $this->browse(function ($browser) use ($user) { $browser->radioB($field, $value)->click(); } but am getting Call to undefined method [radioB]. How do i ref browser instance and trait method? Thanks in advance. – Greenie Oct 08 '20 at 11:48
0

You may not be happy to edit your views for the sake of your test script but if you are open to that, what about adding a class to the

<input type="radio" ... > 

and then using

        ->click('.yourClass') 

in your Dusk test?

CeeGee
  • 416
  • 1
  • 4
  • 13
  • Would be odd, because I would have to add a class for every radio `.myRadioClass1; .myRadioClass2`, but I tried something like that using ids: ``, and doing `->click('#radio1')`, and it did not work – Antonio Carlos Ribeiro Jul 05 '17 at 16:18
  • I tried the class thing and it seemed to work - but you're right, adding a separate class to each element could be annoying. I'll look forward to seeing what other suggestions crop up. – CeeGee Jul 05 '17 at 16:29
0

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

Ryan
  • 22,332
  • 31
  • 176
  • 357