Symfony Panther : cannot run multiple tests at once

969 views Asked by At

I am currently writing tests for my Symfony project, I haven't encountered any problems with regular testing like WebTestCase. But now that I am using Panther for some of them, I encounter errors when I try to launch multiple panther tests at once. The first one always works properly but the next ones get weird errors depending on how I try to arrange them and I can't manage to find an exit out of this.

Here's my code, I've regrouped all of my panther tests in a same class.

namespace App\Tests;

use App\Entity\User;
use App\Repository\TrainingRepository;
use App\Repository\QuestionRepository;
use Symfony\Component\Panther\PantherTestCase;

class PantherTest extends PantherTestCase
{
    public function testCreateTrainingOneUser(): void
    {
        $client = static::createPantherClient();

        $crawler = $client->request('GET', '/');
        $client->submitForm('Sign in', [
            'email'     => '[email protected]',
            'password'  => 'toto']);
        $crawler = $client->request('GET', '/dashboard/training/create_training');
        $this->assertSelectorTextContains('.h3', 'Créer une formation');

        $client->executeScript("document.querySelector('#add_user_button').click()");
        $client->waitFor('#create_training_users_0_email');

        $client->submitForm('Create', [
            "create_training[title]" => 'test',
            "create_training[description]" => 'un test',
            "create_training[image_url]" => 'image_url',
            "create_training[users][0][email]" => 1,
            "create_training[checklist][]" => 'option1',
        ]);
        $trainingRepository = static::$container->get(TrainingRepository::class);

        $testTraining = $trainingRepository->findOneBy(['title' => 'test']);
        $this->assertNotEmpty($testTraining);
    }

    public function testCreateQuestion(): void
    {
        $client = static::createPantherClient();

        $crawler = $client->request('GET', '/');
        $client->submitForm('Sign in', [
            'email'     => '[email protected]',
            'password'  => 'toto']);
        $crawler = $client->request('GET', '/dashboard/training/1/qcm/1/create_question');
        $this->assertSelectorTextContains('.h3', 'Créer une nouvelle question');

        $client->executeScript("document.querySelector('.answer-add').click()");
        $client->waitFor('#create_question_answers_0_label');

        $client->submitForm('Créer', [
            "create_question[label]" => 'test',
            "create_question[hint]" => 'un test',
            "create_question[type]" => 1,
            "create_question[solution]" => 'le test',
            "create_question[associated_chapters]" => 'test1',
            "create_question[state]" => 'en cours',
            "create_question[answers][0][label]" => 'réponse test',
            "create_question[answers][0][is_right]" => true,
            "create_question[answers][0][position]" => 1,
        ]);

        $questionRepository = static::$container->get(QuestionRepository::class);
        $testQuestion = $questionRepository->findOneBy(['label' => 'test', 'qcm' => 1]);
        $this->assertNotEmpty($testQuestion);
    }
}

Both of thoses tests are perfectly functionnal when launched while commenting the other, but if both of them are 'active' only the first one succeeds and I get this error with this current code setup.

✘ Create question
   ┐
   ├ InvalidArgumentException: The current node list is empty.
   │
   ╵ /home/simon/Tek3/Stage/PhysioAc_Login/vendor/symfony/panther/src/DomCrawler/Crawler.php:396
   ╵ /home/simon/Tek3/Stage/PhysioAc_Login/vendor/symfony/panther/src/DomCrawler/Crawler.php:308
   ╵ /home/simon/Tek3/Stage/PhysioAc_Login/vendor/symfony/browser-kit/AbstractBrowser.php:323
   ╵ /home/simon/Tek3/Stage/PhysioAc_Login/tests/PantherTest.php:45

Line 45 is this one there

44- $client->submitForm('Sign in', [
45-            'email'     => '[email protected]',
46-            'password'  => 'toto']);

Since our web site use authentification, I currentmy have to login using the submit form method since loginUser available with WebTestCase doesn't work with Panther.

Update 1 : As suggested by the 1st comment, the "session" might already logged in. Which his indeed the case after a small test

public function testCreateQuestion(): void
    {
        $client = static::createPantherClient();

        $crawler = $client->request('GET', '/dashboard/training/1/qcm/1/create_question');
        $this->assertSelectorTextContains('.h3', 'Créer une nouvelle question');

        /*$client->executeScript("document.querySelector('.answer-add').click()");
        $client->waitFor('#create_question_answers_0_label');

        $client->submitForm('Créer', [
            "create_question[label]" => 'test',
            "create_question[hint]" => 'un test',
            "create_question[type]" => 1,
            "create_question[solution]" => 'le test',
            "create_question[associated_chapters]" => 'test1',
            "create_question[state]" => 'en cours',
            "create_question[answers][0][label]" => 'réponse test',
            "create_question[answers][0][is_right]" => true,
            "create_question[answers][0][position]" => 1,
        ]);

        $questionRepository = static::$container->get(QuestionRepository::class);
        $testQuestion = $questionRepository->findOneBy(['label' => 'test', 'qcm' => 1]);
        $this->assertNotEmpty($testQuestion);*/
    }

This is my new 2nd test, and this assertion works, indicating that I am still considered as logged in and can navigate freely. But now if I uncomment the end of the test, it take a very long time to complete (around 1min with the commented code and around 2mins without)

And without the comment I get the following error

✘ Create question
   ┐
   ├ Facebook\WebDriver\Exception\WebDriverCurlException: Curl error thrown for http POST to /session/fb755275a1734b52965592ca0765e4c4/element/7539b385-285d-4d86-ac88-502835620960/click
   ├                                                                                                                                                                                     
   ├ Operation timed out after 30001 milliseconds with 0 bytes received                                                                                                                  
   │
   ╵ /home/simon/Tek3/Stage/PhysioAc_Login/vendor/php-webdriver/webdriver/lib/Remote/HttpCommandExecutor.php:332
   ╵ /home/simon/Tek3/Stage/PhysioAc_Login/vendor/php-webdriver/webdriver/lib/Remote/RemoteWebDriver.php:591
   ╵ /home/simon/Tek3/Stage/PhysioAc_Login/vendor/php-webdriver/webdriver/lib/Remote/RemoteExecuteMethod.php:27
   ╵ /home/simon/Tek3/Stage/PhysioAc_Login/vendor/php-webdriver/webdriver/lib/Remote/RemoteWebElement.php:76
   ╵ /home/simon/Tek3/Stage/PhysioAc_Login/vendor/symfony/panther/src/Client.php:244
   ╵ /home/simon/Tek3/Stage/PhysioAc_Login/vendor/symfony/browser-kit/AbstractBrowser.php:325
   ╵ /home/simon/Tek3/Stage/PhysioAc_Login/tests/PantherTest.php:50

The line 50 is the one just after the sumbitForm() method.

1

There are 1 answers

0
Ragnarofl On

Got an anwser by my own after all my research.

I simply had to call the following line at the beggining of each test to avoid problems.

self::stopWebServer();

Since Panther clients are asynchronous processes I immagine it can quickly causes very weird problem and it is just more simple to proceed that way.