Search code examples
behat

behat fillField xpath giving error?


This line of code:

$this->fillField('xpath','//fieldset[@id="address-container"]/input[@name="address_add[0][city]"]', "Toronto");

Is giving me this error

Form field with id|name|label|value|placeholder "xpath" not found. (Behat\Mink\Exception\ElementNotFoundException)

The reason I want to use xpath in my fillField is because there are actually multiple input[@name="address_add[0][city]"] in my html document. I figure an xpath will let me target specifically the field I want to populate.

What's the best way to fill out just the input[@name="address_add[0][city]"] that is a descendant of fieldset[@id="address-container"] ?


Solution

  • You are not using the method in the wright way.

    As i see here xpath is taken as selector. The method expects 2 parameters:
    identifier - value of one of attributes 'id|name|label|value'
    value - the string you need to set as value

    If you want to use css|xpath then you need to use find method first.

    For example:

    $this->find('xpath', 'your_selector')->setValue('your_string');
    

    Please note that find might return null and using setValue will result in a fatal exception.

    You should have something like this:

    $field = find('xpath', 'your_selector');
    
    if ($field === null) {
        // throw exception
    }
    
    $field->setValue('your_string');
    

    Also your selector could be written as:

    #address-container input[name*=city] - this with css
    

    or

    //fieldset[@id="address-container"]//input[contains(@name, 'city')]  - this with xpath
    

    Make sure you take advantage of your IDE editor when you have any doubts using a method and you should find a php doc with what parameters are expected and what the method will return.

    If you are using css/xpath a lot you could override find method to detect automatically the type of selector and to use it like $this->find($selector);

    Also you could define another method to wait for the element and to handle the exception in one place, for example waitForElement($selector) that could contain a conditional wait up to 10 seconds and that throws exception if not found.