0

I am trying to perform acceptance tests for my website using Codeception, and I am experiencing a strange error due to a reset button on the form I am testing. Basically, my test for clicking on 'Save' works only if either the reset button on my form is AFTER the Save button, or if the reset button is left off the form altogether. If the reset button is inserted in the form before the save button, Codeception throws an Unreachable field "reset" error. Here is my Codeception code:

<?php
$I = new WebGuy($scenario);
$I->wantTo('find an employee in the database');
$I->amOnPage('/employees/find/');
$I->fillField('employeeLookup[first_name]', 'Sergi');
$I->click('Save', '#employeeLookup_save');
$I->see('Based on your search for Sergi, the following employees were found:');
$I->see('Remmele');
$I->see('Feb 28 1992');

And here is my HTML (much of it being generated from Symfony2):

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <title>Find existing employee</title>
    </head>
    <body>
        <div id="content">
                <p>Hello, enter either the first name, or the last name of the employee
        you are searching for.</p>
    <form name="employeeLookup" method="post" action="">


    <div><label for="employeeLookup_first_name" class="required">Name: </label><input type="text" id="employeeLookup_first_name" name="employeeLookup[first_name]" required="required" /></div>
    <div><button type="reset" id="employeeLookup_reset" name="employeeLookup[reset]">Reset</button></div>
    <div><button type="submit" id="employeeLookup_save" name="employeeLookup[save]">Save</button></div>
    <input type="hidden" id="employeeLookup__token" name="employeeLookup[_token]" value="RcpMVTGgB6WhKgDoXXRwmV_l4AFYKWTZko-dnBDhhvM" /></form>

        </div>

<div id="sfwdte5d291" class="sf-toolbar" style="display: none"></div><script>/*<![CDATA[*/    Sfjs = (function() {        "use strict";        var noop = function() {},            profilerStorageKey = 'sf2/profiler/',            request = function(url, onSuccess, onError, payload, options) {                var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');                options = options || {};                xhr.open(options.method || 'GET', url, true);                xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');                xhr.onreadystatechange = function(state) {                    if (4 === xhr.readyState && 200 === xhr.status) {                        (onSuccess || noop)(xhr);                    } else if (4 === xhr.readyState && xhr.status != 200) {                        (onError || noop)(xhr);                    }                };                xhr.send(payload || '');            },            hasClass = function(el, klass) {                return el.className.match(new RegExp('\\b' + klass + '\\b'));            },            removeClass = function(el, klass) {                el.className = el.className.replace(new RegExp('\\b' + klass + '\\b'), ' ');            },            addClass = function(el, klass) {                if (!hasClass(el, klass)) { el.className += " " + klass; }            },            getPreference = function(name) {                if (!window.localStorage) {                    return null;                }                return localStorage.getItem(profilerStorageKey + name);            },            setPreference = function(name, value) {                if (!window.localStorage) {                    return null;                }                localStorage.setItem(profilerStorageKey + name, value);            };        return {            hasClass: hasClass,            removeClass: removeClass,            addClass: addClass,            getPreference: getPreference,            setPreference: setPreference,            request: request,            load: function(selector, url, onSuccess, onError, options) {                var el = document.getElementById(selector);                if (el && el.getAttribute('data-sfurl') !== url) {                    request(                        url,                        function(xhr) {                            el.innerHTML = xhr.responseText;                            el.setAttribute('data-sfurl', url);                            removeClass(el, 'loading');                            (onSuccess || noop)(xhr, el);                        },                        function(xhr) { (onError || noop)(xhr, el); },                        options                    );                }                return this;            },            toggle: function(selector, elOn, elOff) {                var i,                    style,                    tmp = elOn.style.display,                    el = document.getElementById(selector);                elOn.style.display = elOff.style.display;                elOff.style.display = tmp;                if (el) {                    el.style.display = 'none' === tmp ? 'none' : 'block';                }                return this;            }        }    })();/*]]>*/</script><script>/*<![CDATA[*/    (function () {                Sfjs.load(            'sfwdte5d291',            '/employees/app_dev.php/_wdt/e5d291',            function(xhr, el) {                el.style.display = -1 !== xhr.responseText.indexOf('sf-toolbarreset') ? 'block' : 'none';                if (el.style.display == 'none') {                    return;                }                if (Sfjs.getPreference('toolbar/displayState') == 'none') {                    document.getElementById('sfToolbarMainContent-e5d291').style.display = 'none';                    document.getElementById('sfToolbarClearer-e5d291').style.display = 'none';                    document.getElementById('sfMiniToolbar-e5d291').style.display = 'block';                } else {                    document.getElementById('sfToolbarMainContent-e5d291').style.display = 'block';                    document.getElementById('sfToolbarClearer-e5d291').style.display = 'block';                    document.getElementById('sfMiniToolbar-e5d291').style.display = 'none';                }            },            function(xhr) {                if (xhr.status !== 0) {                    confirm('An error occurred while loading the web debug toolbar (' + xhr.status + ': ' + xhr.statusText + ').\n\nDo you want to open the profiler?') && (window.location = '/employees/app_dev.php/_profiler/e5d291');                }            }        );    })();/*]]>*/</script>
</body>
</html>

Finally, here is the relevant output of the error message from Codeception:

1) Failed to find an employee in the database in FindEmployeeCept.php
Sorry, I couldn't click "Save","#employeeLookup_save":
Behat\Mink\Exception\ElementException: Exception thrown by ((//html/descendant-or-self::*[@id = 'employeeLookup_save'])[1]/.//input[./@type = 'submit' or ./@type = 'image' or ./@type = 'button'][(((./@id = 'Save' or ./@name = 'Save') or contains(./@value, 'Save')) or contains(./@title, 'Save'))] | .//input[./@type = 'image'][contains(./@alt, 'Save')] | .//button[((((./@id = 'Save' or ./@name = 'Save') or contains(./@value, 'Save')) or contains(normalize-space(string(.)), 'Save')) or contains(./@title, 'Save'))] | .//input[./@type = 'image'][contains(./@alt, 'Save')] | .//*[./@role = 'button'][(((./@id = 'Save' or ./@name = 'Save') or contains(./@value, 'Save')) or contains(./@title, 'Save') or contains(normalize-space(string(.)), 'Save'))])[1]
Unreachable field "reset"

Again, if the reset button is rendered after the save button in the HTML, the acceptance tests pass just fine. Also, if the reset button is left off of the form entirely, the acceptance test passes as well. Does anyone have any idea what is causing this?

Byte Lab
  • 1,576
  • 2
  • 17
  • 42
  • These are other variations of the arguments I have passed to the click function in my Codeception code: $I->click('Save'); $I->click('#employeeLookup_save'); $I->click('employeeLookup[save]); $I->click('submit'); None of these have worked either. – Byte Lab Feb 03 '14 at 15:11
  • Works for me. What version of Codeception are you using? – akond Feb 05 '14 at 15:17
  • I am using version 1.8.0. What version are you using? – Byte Lab Feb 05 '14 at 19:40
  • Codeception version 1.8.1 – akond Feb 06 '14 at 07:07
  • Sigh...1.8.1 has all sorts of dependencies. I'll just stick with 1.8.0 and hack the test by moving the reset button per my description above. Thanks for the pointer though. – Byte Lab Feb 06 '14 at 17:13

0 Answers0