13

I get "InvalidArgumentException: The current node list is empty." running functional tests through PHPUnit. Here is test i wrote:

public function testAdd()
{
    $client = static::createClientWithAuthentication('main');

    $crawler = $client->request('GET', 'en/manage');

    $send_button = $crawler->selectButton('submit');

    $form = $send_button->form(array(
        'PrCompany[email]' => 'test@example.ua',
        'PrCompany[first_name]' => 'Anton',
        'PrCompany[last_name]' => 'Tverdiuh',
        'PrCompany[timezone]' => 'Europe/Amsterdam'
    ));

    $form['PrCompany[companies][1]']->tick();

    $client->submit($form);


    $this->assertTrue($crawler->filter('html:contains("User is invited")')->count() > 0);

}
VitalyP
  • 1,867
  • 6
  • 22
  • 31
  • I think I have a similar question which may help you understand your issue more. No answers yet... http://stackoverflow.com/questions/9662697/symfony2-functional-testing-crawler-not-working – Matt Mar 12 '12 at 06:37
  • You have not marked any question as the answer, so I will add my own, hopefully solving yor question – Andrew Atkinson Jul 11 '13 at 10:06
  • I think you need to use `$form['PrCompany[companies]'][1]->tick(); ` (with the [1] outside of the quotes) – caponica Oct 16 '13 at 22:20
  • Hi @vitalyp ! Did you found answer to this question? I'm struggling with the same problem. Looks like #goutte dont like form input element with array name "name[]". – wormhit Apr 01 '14 at 13:59

7 Answers7

13

You can debug the problem by using var_dump($client->getResponse()->getContent());

Additionally, I think you should write this:

$crawler = $client->submit($form);

Otherwise you'll be testing the response of the first url, before form submission.

greg0ire
  • 22,714
  • 16
  • 72
  • 101
9

I was also struggling with this, and It appeared that the selectButton method triggered this error.

After reading up on the DOM Crawler docs I found that the selectButton method takes the actual button text as a string argument. So if your button is 'submit my form please', that will be your text.

It does take different parameters too, as shown below (taken from the docs)

A selectButton() method is available on the Crawler which returns another 
Crawler that matches a button (input[type=submit], input[type=image], 
or a button) with the given text.

EDIT

After finally successfully completing the test I would also recommend you follow this example for testing forms:

use Goutte\Client;

$client = new Client();
$crawler = $client->request('GET', 'https://github.com/login');

$form = $crawler->selectButton('Log in')->form();
$form['login'] = 'symfonyfan';
$form['password'] = 'anypass';

$crawler = $client->submit($form);
$this->assertTrue($crawler->filter('html:contains("Welcome Back")')->count() > 0);

The main difference being, I have used the Goutte bundle, which I installed with composer from the packagist (in my case I added "fabpot/goutte": "1.0.*@dev")

Andrew Atkinson
  • 4,103
  • 5
  • 44
  • 48
2

I had the same problem with Silex application. I was looking for

$buttonCrawler = $crawler->selectButton('input[type="submit"]');

Instead, the correct way to do it is give the value of the button

$buttonCrawler = $crawler->selectButton('value_of_the_button');


For example, in your page:

<form>
    ...
    <input type="submit" value="Click Me">
</form>


And in your tests:

$buttonCrawler = $crawler->selectButton('Click Me');
$form = $buttonCrawler->form();
...
2

As a follow up to what @greg0ire wrote, check to see if

var_dump($client->getResponse()->getContent());

Returns a redirect page instead of the actual content. If so, you can add this:

$client->followRedirects(true);
Matt
  • 5,478
  • 9
  • 56
  • 95
1

I see question still dont have answer. I had the same problem.

In my case goutte was not able to do this request because input name is changed by javascript on the fly.

When goutte received html it saw one form. And when submitting with pre filled params, form input elements could not be matched by $form->setValues($params) so \InvalidArgumentException was thrown.

Solved by doing request by hand.

// $form->setValues($data);
// $this->getGoutte()->submit($form);

$data = array(
    'input_name[key]' => 'value'
);
$this->getGoutte()->request($form->getMethod(), $form->getUri(), $params);
wormhit
  • 3,687
  • 37
  • 46
0

This error would occur when crawler can't find form element requested; Quite tricky when you are using, for instance, form builder as when run, it will create different input name:

$form = $this-> createFormBuilder($store)
           ->add('storeNumber','text')
           ->add('storeName','text')
           ->add('save', 'submit')
           ->getForm(); 

will output field name like:

form_storeNumber

which should be used in test class:

$form=$crawler->selectButton('save')->form();
$form['form_storeNumber']='10';
Michal
  • 35
  • 6
0

You can try to use Codeception with Symfony2 module. It provides flexible interface to Symfony2 functional tests and has better debugging features.

Davert
  • 314
  • 1
  • 5