magic-test/magic-test-laravel

TypeError when running `ok` after actions

rhys-steele opened this issue · 8 comments

Description

After installing Magic Test and following the installation and usage instructions I am receiving the following error after running the ok or finish commands.

TypeError: Typed property MagicTest/MagicTest/Parser/File::$initialMethodLine must be an instance of MagicTest/MagicTest/Parser/Line, null used

I am using the testBasicExample method of the ExampleTest in my browser tests as per the usage guide. The contents of my test is

<?php

namespace Tests\Browser;

use Illuminate\Foundation\Testing\DatabaseMigrations;
use Laravel\Dusk\Browser;
use Tests\DuskTestCase;

class ExampleTest extends DuskTestCase
{
    /**
     * A basic browser test example.
     *
     * @return void
     */
    public function testBasicExample()
    {
        $this->browse(function (Browser $browser) {
            $browser->visit('/')
                    ->magic();
        });
    }
}

Specifications

  • PHP Version: 7.4.13
  • Laravel Version: 8.9.0

Thanks for the information. I'll look into this in the morning, seems to be something with the parser.
Can you let me know which OS are you using?

@rhys-steele can you also post the full stacktrace?

No worries.
Cheers for taking a look at the issue!

System Information
MacOS Catalina
10.15.7

Stack Trace

TypeError: Typed property MagicTest/MagicTest/Parser/File::$initialMethodLine must be an instance of MagicTest/MagicTest/Parser/Line, null used
--
 0:  () at vendor/psy/psysh/src/Exception/TypeErrorException.php:53
 1:  Psy\Exception\TypeErrorException::fromTypeError() at vendor/psy/psysh/src/ExecutionLoopClosure.php:91
 2:  Psy\{closure}() at vendor/psy/psysh/src/ExecutionClosure.php:96
 3:  Psy\ExecutionClosure->execute() at vendor/psy/psysh/src/Shell.php:370
 4:  Psy\Shell->doInteractiveRun() at vendor/psy/psysh/src/Shell.php:341
 5:  Psy\Shell->doRun() at vendor/symfony/console/Application.php:142
 6:  Symfony\Component\Console\Application->run() at vendor/psy/psysh/src/Shell.php:316
 7:  Psy\Shell->run() at vendor/magic-test/magic-test-laravel/src/MagicTestManager.php:45
 8:  MagicTest\MagicTest\MagicTestManager::run() at vendor/magic-test/magic-test-laravel/src/MagicTestServiceProvider.php:31
 9:  Laravel\Dusk\Browser->MagicTest\MagicTest\{closure}() at n/a:n/a
10:  call_user_func_array() at vendor/laravel/framework/src/Illuminate/Macroable/Traits/Macroable.php:111
11:  Laravel\Dusk\Browser->macroCall() at vendor/laravel/dusk/src/Browser.php:658
12:  Laravel\Dusk\Browser->__call() at tests/Browser/LoginTest.php:20
13:  Tests\Browser\LoginTest->Tests\Browser\{closure}() at vendor/laravel/dusk/src/Concerns/ProvidesBrowser.php:68
14:  Laravel\Dusk\TestCase->browse() at tests/Browser/LoginTest.php:21
15:  Tests\Browser\LoginTest->testBasicExample() at vendor/phpunit/phpunit/src/Framework/TestCase.php:1536
16:  PHPUnit\Framework\TestCase->runTest() at vendor/phpunit/phpunit/src/Framework/TestCase.php:1142
17:  PHPUnit\Framework\TestCase->runBare() at vendor/phpunit/phpunit/src/Framework/TestResult.php:730
18:  PHPUnit\Framework\TestResult->run() at vendor/phpunit/phpunit/src/Framework/TestCase.php:883
19:  PHPUnit\Framework\TestCase->run() at vendor/phpunit/phpunit/src/Framework/TestSuite.php:669
20:  PHPUnit\Framework\TestSuite->run() at vendor/phpunit/phpunit/src/Framework/TestSuite.php:669
21:  PHPUnit\Framework\TestSuite->run() at vendor/phpunit/phpunit/src/Framework/TestSuite.php:669
22:  PHPUnit\Framework\TestSuite->run() at vendor/phpunit/phpunit/src/TextUI/TestRunner.php:673
23:  PHPUnit\TextUI\TestRunner->run() at vendor/phpunit/phpunit/src/TextUI/Command.php:148
24:  PHPUnit\TextUI\Command->run() at vendor/phpunit/phpunit/src/TextUI/Command.php:101
25:  PHPUnit\TextUI\Command::main() at vendor/phpunit/phpunit/phpunit:61

@rhys-steele thanks!
I see on the stack trace that you're calling it from tests/Browser/LoginTest.php. Any chance you can paste that file content here?

For some reason it is not being able to figure out initial method line. MT fetches that through a debug_backtrace.

`

The tests/Browser/LoginTest.php was a file created through running php artisan dusk:make LoginTest. It wasn't the file contents that I originally posted but it was the same error and the same code.

<?php

namespace Tests\Browser;

use Illuminate\Foundation\Testing\DatabaseMigrations;
use Laravel\Dusk\Browser;
use Tests\DuskTestCase;

class LoginTest extends DuskTestCase
{
    /**
     * A Dusk test example.
     *
     * @return void
     */
    public function testBasicExample()
    {
        $this->browse(function (Browser $browser) {
            $browser->visit('/')
                    ->magic();
        });
    }
}

@rhys-steele that's super weird, just made a fresh installation and created a file with the exact same content and it works.

Once the shell opens, before writing a command, could you type the following:

MagicTest\MagicTest\MagicTest::$file;
MagicTest\MagicTest\MagicTest::$method;
explode("\n", file_get_contents(MagicTest\MagicTest\MagicTest::$file));

Magic Test converts the file content in an array, and then matches a line that contains public function $methodName. So I'd like to see these contents...

If you're willing, we could get on a quick call to figure this out.

Thanks for helping out!

Here's the output

Your Magic Test session has started!
>>> MagicTest\MagicTest\MagicTest::$file;
=> "/path/to/project/vendor/magic-test/magic-test-laravel/src/MagicTestServiceProvider.php"
>>> MagicTest\MagicTest\MagicTest::$method;
=> "macroCall"
>>> explode("\n", file_get_contents(MagicTest\MagicTest\MagicTest::$file));
=> [
     "<?php",
     "",
     "namespace MagicTest\MagicTest;",
     "",
     "use Illuminate\Support\Facades\Blade;",
     "use Laravel\Dusk\Browser;",
     "use MagicTest\MagicTest\Commands\MagicTestCommand;",
     "use MagicTest\MagicTest\Controllers\MagicTestController;",
     "use Spatie\LaravelPackageTools\Package;",
     "use Spatie\LaravelPackageTools\PackageServiceProvider;",
     "",
     "class MagicTestServiceProvider extends PackageServiceProvider",
     "{",
     "    public function configurePackage(Package $package): void",
     "    {",
     "        /*",
     "         * This class is a Package Service Provider",
     "         *",
     "         * More info: https://github.com/spatie/laravel-package-tools",
     "         */",
     "        $package",
     "            ->name('magic-test-laravel')",
     "            ->hasCommand(MagicTestCommand::class);",
     "    }",
     "",
     "    public function boot()",
     "    {",
     "        parent::boot();",
     "",
     "        $this->app->singleton('magic-test-laravel', fn ($app) => new MagicTest);",
     "        Browser::macro('magic', fn () => MagicTestManager::run($this));",
     "",
     "        Blade::directive('magicTestScripts', [MagicTest::class, 'scripts']);",
     "    }",
     "",
     "    protected function registerRoutes()",
     "    {",
     "        if (MagicTest::running()) {",
     "            return;",
     "        }",
     "",
     "        app('router')->post('/magic-test', MagicTestController::class);",
     "    }",
     "}",
     "",
   ]
>>> 

Happy to jump on a call to discuss if that would help. Assuming that the MagicTest\MagicTest\MagicTest::$file shouldn't be the MagicTestServiceProvider.php but rather my LoginTest.php file?

@rhys-steele sorry for coming back to this so late — I missed your last reply.

You're right, that shouldn't be the file.
That's pretty crazy — I wasn't able to reproduce the error, but I'll add some checks to make sure it does not pick that file.