Completed
Push — master ( 97f2e9...a6bde0 )
by Marcel
02:00
created

src/Console/StartDashboardCommand.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace BeyondCode\DuskDashboard\Console;
4
5
use Clue\React\Buzz\Browser;
6
use Illuminate\Console\Command;
7
use Ratchet\WebSocket\WsServer;
8
use React\EventLoop\LoopInterface;
9
use Symfony\Component\Finder\Finder;
10
use Symfony\Component\Routing\Route;
11
use BeyondCode\DuskDashboard\Watcher;
12
use Symfony\Component\Process\Process;
13
use React\EventLoop\Factory as LoopFactory;
14
use BeyondCode\DuskDashboard\Ratchet\Socket;
15
use BeyondCode\DuskDashboard\Ratchet\Server\App;
16
use BeyondCode\DuskDashboard\Ratchet\Http\EventController;
17
use BeyondCode\DuskDashboard\Ratchet\Http\DashboardController;
18
19
class StartDashboardCommand extends Command
20
{
21
    const PORT = 9773;
22
23
    protected $signature = 'dusk:dashboard';
24
25
    protected $description = 'Start the Laravel Dusk Dashboard';
26
27
    /** @var App */
28
    protected $app;
29
30
    /** @var LoopInterface */
31
    protected $loop;
32
33
    public function handle()
34
    {
35
        $url = parse_url(config('dusk-dashboard.host', config('app.url')));
36
37
        $this->loop = LoopFactory::create();
38
39
        $this->loop->futureTick(function () use ($url) {
40
            $dashboardUrl = 'http://'.$url['host'].':'.self::PORT.'/dashboard';
41
42
            $this->info('Started Dusk Dashboard on port '.self::PORT);
43
44
            $this->info('Your Dusk tests are now being watched.');
45
46
            $this->info('If the dashboard does not automatically open, visit: '.$dashboardUrl);
47
48
            $this->tryToOpenInBrowser($dashboardUrl);
49
        });
50
51
        $this->createTestWatcher();
52
53
        $this->createApp($url);
54
    }
55
56
    protected function addRoutes()
57
    {
58
        $eventRoute = new Route('/events', ['_controller' => new EventController()], [], [], null, [], ['POST']);
59
60
        $this->app->routes->add('events', $eventRoute);
61
62
        $dashboardRoute = new Route('/dashboard', ['_controller' => new DashboardController()], [], [], null, [], ['GET']);
63
64
        $this->app->routes->add('dashboard', $dashboardRoute);
65
    }
66
67
    protected function createTestWatcher()
68
    {
69
        $finder = (new Finder)
70
            ->name('*.php')
71
            ->files()
72
            ->in($this->getTestSuitePath());
73
74
        (new Watcher($finder, $this->loop))->startWatching(function () {
75
            $client = new Browser($this->loop);
76
77
            $client->post('http://127.0.0.1:'.StartDashboardCommand::PORT.'/events', [
78
                'Content-Type' => 'application/json',
79
            ], json_encode([
80
                    'channel' => 'dusk-dashboard',
81
                    'name' => 'dusk-reset',
82
                    'data' => [],
83
                ])
84
            );
85
86
            $process = new Process('php artisan dusk', base_path());
0 ignored issues
show
'php artisan dusk' is of type string, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
87
88
            $process->start();
89
        });
90
    }
91
92
    protected function getTestSuitePath()
93
    {
94
        $directories = [];
95
96
        if (file_exists(base_path('phpunit.dusk.xml'))) {
97
            $xml = simplexml_load_file(base_path('phpunit.dusk.xml'));
98
99
            foreach ($xml->testsuites->testsuite as $testsuite) {
100
                $directories[] = (string) $testsuite->directory;
101
            }
102
        } else {
103
            $directories[] = base_path('tests/Browser');
104
        }
105
106
        return $directories;
107
    }
108
109
    protected function createApp(array $url)
110
    {
111
        $socket = new Socket();
112
113
        $this->app = new App($url['host'], self::PORT, '0.0.0.0', $this->loop);
114
115
        $this->app->route('/socket', new WsServer($socket), ['*']);
116
117
        $this->addRoutes();
118
119
        $this->app->run();
120
    }
121
122
    protected function tryToOpenInBrowser($url)
123
    {
124
        if (PHP_OS === 'Darwin') {
125
            exec('open '.$url);
126
        }
127
    }
128
}
129