Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug when select radiobuttons in Yii #586

Closed
ayvan opened this issue Oct 1, 2013 · 18 comments

Comments

Projects
None yet
6 participants
@ayvan
Copy link

commented Oct 1, 2013

My form in Yii (radioButtonListRow):

<label class="required" for="ClientSelectProductForm2_product">
Select product<span class="required">*</span></label>
<input id="ytClientSelectProductForm2_product" type="hidden" name="ClientSelectProductForm2[product]" value="">
<label class="radio">
<input id="ClientSelectProductForm2_product_0" class="all" type="radio" name="ClientSelectProductForm2[product]" value="1">
<label for="ClientSelectProductForm2_product_0">
<span>Product 1</span>
</label>
</label>
<label class="radio">
<input id="ClientSelectProductForm2_product_1" class="all" type="radio" name="ClientSelectProductForm2[product]" value="2">
<label for="ClientSelectProductForm2_product_1">
<span>Product 2</span>
</label>
</label>

My test:

$I = new WebGuy($scenario);
$I->wantTo('Test select product');
$I->amOnPage('/form'); 
$I->seeElement('form input[name="ClientSelectProductForm2[product]"]'); //OK
$I->selectOption('form input[name="ClientSelectProductForm2[product]"]', 'Product 1');

PHP Fatal error: Call to undefined method Symfony\Component\DomCrawler\Field\InputFormField::addChoice() in phar:///var/www/ru.dev.kreddy/protected/codecept.phar/vendor/symfony/dom-crawler/Symfony/Component/DomCrawler/Form.php on line 413

Or:

$I->seeElement('#ClientSelectProductForm2_product_0'); //OK
$I->click('#ClientSelectProductForm2_product_0'); //Error

@ayvan ayvan closed this Oct 1, 2013

@ayvan ayvan reopened this Oct 1, 2013

@aditya-

This comment has been minimized.

Copy link
Contributor

commented Oct 1, 2013

@ayvan

Sorry its not a bug .. you should use checkOption to select radio buttons .. here i am using id name .. which works for me ..

you may give scenario like this : 

$I->checkOption('#ClientSelectProductForm2_product_0'); // checking radio button

or else you may use 

$I->checkOption('input[type="radio"]'); //checking first option 

@ayvan

This comment has been minimized.

Copy link
Author

commented Oct 1, 2013

$I->seeElement('#ClientSelectProductForm2_product_0');
$I->checkOption('#ClientSelectProductForm2_product_0');
  • I am on page "/form"
  • I see "Сумма займа"
  • I see element "#ClientSelectProductForm2_product_0"
  • I check option "#ClientSelectProductForm2_product_0"
    PHP Fatal error: Call to undefined method Symfony\Component\DomCrawler\Field\InputFormField::addChoice() in phar:///var/www/ru.dev.kreddy/protected/codecept.phar/vendor/symfony/dom-crawler/Symfony/Component/DomCrawler/Form.php on line 413
$I->checkOption('input[type="radio"]');
  • I am on page "/form"
  • I see "Сумма займа"
  • I see element "#ClientSelectProductForm2_product_0"
  • I check option "input[type="radio"]"
    PHP Fatal error: Call to undefined method Symfony\Component\DomCrawler\Field\InputFormField::addChoice() in phar:///var/www/ru.dev.kreddy/protected/codecept.phar/vendor/symfony/dom-crawler/Symfony/Component/DomCrawler/Form.php on line 413
@aditya-

This comment has been minimized.

Copy link
Contributor

commented Oct 1, 2013

its saying that you dont have checkOption method ..

once post your acceptance.yml file here @ayvan

@ayvan

This comment has been minimized.

Copy link
Author

commented Oct 1, 2013

I have checkOption method in my WebGuy, but when I call it, Codeception can't find "Symfony\Component\DomCrawler\Field\InputFormField::addChoice()" method, because Yii generate hidden fild with same name as radiobutton's name, and DomCrawler want to "checkOption: on first item with this name, and it's hidden field. But hidden filed can't have addChoice() method.

My acceptance.yml:

class_name: WebGuy
modules:
    enabled:
        - PhpBrowser
        - WebHelper
    config:
        PhpBrowser:
            url: 'http://test.server/'
@aditya-

This comment has been minimized.

Copy link
Contributor

commented Oct 1, 2013

@ayvan ..

ok got ..

change acceptance.yml to :

class_name: WebGuy
modules:
    enabled:
        - WebHelper
        - PhpBrowser

    config:
        PhpBrowser:
            url: 'http://test.server/'

and download latest codeception like this

for update:

wget http://codeception.com/codecept.phar -O codecept.phar

then give build command

php codecept.phar build

.. Now run your test cases .. it may work

@ayvan

This comment has been minimized.

Copy link
Author

commented Oct 1, 2013

Still has error:

$I->seeElement('#ClientSelectProductForm2_product_0');
$I->checkOption('#ClientSelectProductForm2_product_0');
Codeception PHP Testing Framework v1.6.7
Powered by PHPUnit 3.7.25 by Sebastian Bergmann.

Suite acceptance started
Trying to test account login (AccountCept.php)
Scenario:
* I am on page "/form"
* I see "Сумма займа"
* I see element "#ClientSelectProductForm2_product_0"
* I check option "#ClientSelectProductForm2_product_0"
PHP Fatal error:  Call to undefined method Symfony\Component\DomCrawler\Field\InputFormField::addChoice() in phar:///var/www/ru.dev.kreddy/protected/codecept.phar/vendor/symfony/dom-crawler/Symfony/Component/DomCrawler/Form.php on line 413
@aditya-

This comment has been minimized.

Copy link
Contributor

commented Oct 1, 2013

@ayvan

once refer this issue ..

#99

@DavertMik

This comment has been minimized.

Copy link
Member

commented Oct 3, 2013

For radiobuttons use selectOption instead.

@ayvan

This comment has been minimized.

Copy link
Author

commented Oct 3, 2013

I got

PHP Fatal error: Call to undefined method Symfony\Component\DomCrawler\Field\InputFormField::addChoice() in phar:///var/www/ru.dev.kreddy/protected/codecept.phar/vendor/symfony/dom-crawler/Symfony/Component/DomCrawler/Form.php on line 413

when use selectOption. DomCrawler tryes to call addChoice on hidden input.

@aditya-

This comment has been minimized.

Copy link
Contributor

commented Oct 3, 2013

Hidden elements can't be accessed via phpbrowser or selenium

@ayvan

This comment has been minimized.

Copy link
Author

commented Oct 7, 2013

@aditya- I know, but when I use Codeception+Yii for acceptance tests, I got fatal error, because in my form hidden element has same name with radiobuttons.

@aditya-

This comment has been minimized.

Copy link
Contributor

commented Oct 7, 2013

yes i am too using codeception inside yii framework for acceptance and unit tests .. i have integrated codeception with yii framework so that i can use yii functions in my test cases .. thats additional advantage ..

but here the thing is that there is no issue with framework .. the problem is that ..

phpbrowser or selenium both cannot access

1. Hidden elements
2. Read-only elements
3. css with display:none elements

this means that you cant fill the fields .. as i can see that

type="hidden" in

<input id="ytClientSelectProductForm2_product" type="hidden" name="ClientSelectProductForm2[product]" value="">
@tomtomsen

This comment has been minimized.

Copy link

commented Jan 9, 2014

to all upcoming people with the same problem.
this is what i found out:

this problem occures in yii, but can also appear in other scenarios, where a none - radio/checkbox is in front of a radio/checkbox.

yii generates a hidden field before a list of radio/checkbox fields. it must be before the other fields, because otherwise they will be overwritten.

<input type="hidden" name="Form[inputfield]" value="unchecked">
<input type="radio" name="Form[inputfield]" value="first">
<input type="radio" name="Form[inputfield]" value="second">

yii does this to get a "uncheck" value in the post/get request. this method is valid html code.

now you need to know PhpBrowser uses Goutte, Goutte uses Mink and Mink uses symfony's DomCrawler.
when working with a form, Symfony\Component\DomCrawler\Form.php adds all fields with a name to a "fieldlist".

foreach ($fieldNodes as $node) {
   $this->addField($node);
}

(https://github.com/symfony/DomCrawler/blob/master/Form.php#L393)

Now here is the problem: addField adds all input fields by their name to that array.
so, first it finds the hidden input field, adds it to the array. next if finds a radio button with the same name, so it thinks it must be a Symfony\Component\DomCrawler\Field\ChoiceFormField, because there is already a field with the exact same name and the current field is radio button.
Now it calls addChoice, which fails, because in fact it is a Symfony\Component\DomCrawler\Field\InputFormField

private function addField(\DOMNode $node)
    {
        if (!$node->hasAttribute('name') || !$node->getAttribute('name')) {
            return;
        }

        $nodeName = $node->nodeName;
        if ('input' == $nodeName && 'radio' == $node->getAttribute('type')) {
            if ($this->has($node->getAttribute('name'))) {
                $this->get($node->getAttribute('name'))->addChoice($node);
            } else {
                $this->set(new Field\ChoiceFormField($node));
            }
        } elseif ('input' == $nodeName && !in_array($node->getAttribute('type'), array('submit', 'button', 'image'))) {
            $this->set(new Field\InputFormField($node));
        }
    }

(reduced version - full version @ https://github.com/symfony/DomCrawler/blob/master/Form.php#L431)

in conclusion

in my opinion, there is no solution to this problem.

you cant select a radio/checkbox with a different field with the same name in front of it. it doesnt matter if it is a text-field, textarea. if it is hidden or not.

@veades

This comment has been minimized.

Copy link

commented Jan 16, 2014

We had the same problem testing our Yii application with Codeception.

The solution that worked for us was to go back to our Yii application and look at the forms that used checkboxes and radio buttons to re-evaluate whether or not we needed a hidden field to store a value for "unchecked".

In every case we found that we didn't need it, so we changed our forms so that those hidden fields wouldn't be added.

http://www.yiiframework.com/doc/api/1.1/CHtml#radioButton-detail

Now our codeception tests on forms work fine.

@DavertMik

This comment has been minimized.

Copy link
Member

commented Jan 16, 2014

Also I think you can hook the Yii forms component for not to render the hidden fields in testing mode.
If you know how to do this, you can help us improve the YiiBridge project https://github.com/Codeception/YiiBridge

@veades

This comment has been minimized.

Copy link

commented Jan 16, 2014

Thanks, DavertMik. I wasn't aware of the YiiBridge project.

I will definitely look into trying it in the near future. (We have many more tests to write to this could be a big help!). And if I can contribute any fixes -- I will definitely do that.

@Ragazzo

This comment has been minimized.

Copy link
Contributor

commented Feb 7, 2014

@DavertMik mark it with Yii tag, will look closer on this one later.

@DavertMik

This comment has been minimized.

Copy link
Member

commented Jul 21, 2014

Outdated. Reopen if it is still relevant

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.