3

I have a form, without action (is submitted with javascript) and I'm trying to write a unit test for it, but it fails because "action" attribute is missing:

InvalidArgumentException : Current URI must be an absolute URL ("").

There is a way to do add it in unit tests or modify the html content using the crawler?

<form id="form_search_page">
    <input type="text" name="keyword" value="" />
    <button type="submit" name="searchBtn" id="searchBtn">Search</button>
</form>


$client = $this->makeClient(true);
$url = $this->createRoute("page_index"));
$crawler = $client->request('GET', $url);
$response = $client->getResponse();

$form = $crawler->filter('#form_search_page')->form();
$params = array(
    "form[text]" => "dummy title"
);
$form->setValues($params);
$crawler = $client->submit($form);
$response = $client->getResponse();
$this->assertGreaterThan(0, $crawler->filter('.pages li')->count());

3 Answers 3

3

I found the solution:

$crawler
    ->filter('form#form_search_page')
    ->reduce(function (Crawler $form) use ($router) {
        $url = $router->generate('search_page', array(), true);

        $node = $form->getNode(0);
        if (!$node->hasAttribute('action')){
            $node->setAttribute('action', $url);
            $node->setAttribute('method', 'POST');
            return true;
        }
        return false;
    })
    ->first();
Sign up to request clarification or add additional context in comments.

Comments

2

You could test a ajax POST form submit as example above (Assuming a form with a CSRF token):

$crawler = $this->client->request('GET', $url);

// retrieves the form token
$token = $crawler->filter('[name="myform[_token]"]')->attr("value");

$posturl = $this->client->getContainer()->get('router')->generate("the-url-of-the-submit");
// makes the POST request
$crawler = $this->client->request('POST', $posturl, array(
    'myform' => array(
        '_token' => $token
    )),
    array(),
    array(
        'HTTP_X-Requested-With' => 'XMLHttpRequest',
    )
);

$this->assertTrue(
    $this->client->getResponse()->headers->contains(
        'Content-Type',
        'application/json'
    )
);

Hope this help

2 Comments

Thank your for your feedback, I fixed it following my first idea, manipulate html using the crawler
Hi @CristianBujoreanu if this or any answer has solved your question please consider accepting it and/or upvote by clicking the check-mark. This indicates to the wider community that you've found a solution and gives some reputation to both the answerer and yourself. There is no obligation to do this.
0

Here is the easiest way:

        $client = static::createClient();

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

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

        // Select the form that contains this button
        $form = $buttonCrawlerNode->form();

        // Modify the attribute action
        $form->getNode(0)->setAttribute('action', 'new-action-url');

        ...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.