filament icon indicating copy to clipboard operation
filament copied to clipboard

fillForm() appears to be broken since it can accept Closure in v3.2.77

Open peterbabic opened this issue 10 months ago • 3 comments

Package

filament/forms

Package Version

v3.2.137

Laravel Version

v11.41.3

Livewire Version

v3.5.12

PHP Version

8.4.3

Problem description

I have traced that upgrade of Filament from v3.2.76 to v3.2.77 breaks Laravel Dusk tests using fillForm() - the data in the form are always empty in all versions between v3.2.77 till at least v3.2.137 (current at the time of writing)

https://github.com/filamentphp/filament/compare/v3.2.76...v3.2.77#diff-eab80cbdc04e95db87de932c13eb10bc20b8734a930ff88999fa3777e784971bL35

Expected behavior

The form is actually filled in the test.

Steps to reproduce

If you run :

composer require "filament/filament=3.2.77" -W
php artisan dusk

The fillForm() does not work as I would expect - the test fails like this:

   FAIL  Tests\Browser\TestTest
  ⨯ admin can create test                                                                                                                                                             0.22s
  ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
   FAILED  Tests\Browser\TestTest > admin can create test
  Component has errors: "data.make"
Failed asserting that false is true.

  at vendor/livewire/livewire/src/Features/SupportValidation/TestsValidation.php:109
    105▕     {
    106▕         $errors = $this->errors();
    107▕
    108▕         if (empty($keys)) {
  ➜ 109▕             PHPUnit::assertTrue($errors->isEmpty(), 'Component has errors: "'.implode('", "', $errors->keys()).'"');
    110▕
    111▕             return $this;
    112▕         }
    113▕

      +4 vendor frames
  5   tests/Browser/TestTest.php:18

By running pre-prepared dd() at TestTest.php:20

Illuminate\Support\MessageBag^ {#3620
  #messages: array:1 [
    "data.make" => array:1 [
      0 => "The make field is required."
    ]
  ]
  #format: ":message"
} // tests/Browser/TestTest.php:20

To fix the problem downgrade Filament to v3.2.76:

composer require "filament/filament=3.2.76" -W
php artisan dusk

Now the test passes:

   PASS  Tests\Browser\TestTest
  ✓ admin can create test                                                                                                                                                             0.29s

  Tests:    1 passed (6 assertions)
  Duration: 0.33s

Reproduction repository (issue will be closed if this is not valid)

https://github.com/peterbabic/filament-issue/

Relevant log output


peterbabic avatar Feb 08 '25 19:02 peterbabic

Having the same issue starting from 3.2.136

martinsjek avatar Mar 05 '25 09:03 martinsjek

Faced a similar issue myself, although not with Dusk specifically but with using fillForm in regular tests too, meaning all fields stayed empty. Manually setting them through ->set("data.my_field", "test") worked like a charm however, which led me to further debugging fillForm([...]) and analyzing the diff between v3.2.76 and v3.2.77, specifically this commit: https://github.com/filamentphp/filament/commit/4e605c6dba871b825e3a939a6edcda2b5f95cdfe

A key difference that has been introduced by this change was no longer calling ->set() directly, but instead reaching out to fillFormDataForTesting() of the InteractWithForms trait. In my case I quickly noticed that this new function was not really doing much, as the following check caused it to immediately exit at its very beginning:

https://github.com/filamentphp/filament/blob/03b2131b86efca078875b6ee04b610d6273b1a58/packages/forms/src/Concerns/InteractsWithForms.php#L61-L63

As it turns out, I simply had a stray environment variable in one testing environment that happened to override the default env of a Laravel Application, so it was not set to testing as it should have been. This somehow did not cause problems elsewhere, but as the new fillFormDataForTesting() method specifically checks the environment, all fillForm() calls have essentially been a no-op, with the exception of upload files as they are handled differently.

This might be unrelated to this specific issue; can't say as I am not using Dusk at the moment. I did happen to stumble across it though while searching for my problem, so if anyone else notices that ->set() works but ->fillForm() does not, it is well worth checking if app()->runningUnitTests() is true.

ppmathis avatar May 28 '25 21:05 ppmathis

faced a similar issue. Not sure if filament is interpreting fillForm wrong or if there were changes in fillForm.

I opted for a workaround using fill

livewire(CreateUser::class)
        ->fill([
            'data' => [
                'name' => $name,
                'email' => $email,
            ],
        ])
        ->call('create')
        ->assertHasNoFormErrors();

FYI the password is autogenerated so not part of this form

hussamitani avatar Jun 10 '25 09:06 hussamitani

I have pulled down the reproduction issue to test, and as @ppmathis the issue is that the APP_ENV for your browser tests is set to local and not testing. If you switch the environment to testing, everything works as expected

We have the testing environment check to ensure that users of Filament cant call various testing-only helper methods from outside a testing environment.

danharrin avatar Jun 22 '25 20:06 danharrin