breakign dusk tests
This commit is contained in:
+115
-22
@@ -12,16 +12,26 @@ abstract class DuskTestCase extends BaseTestCase
|
||||
{
|
||||
use CreatesApplication;
|
||||
|
||||
/**
|
||||
* Keep the local Laravel server process alive for the Dusk run.
|
||||
*
|
||||
* @var resource|null
|
||||
*/
|
||||
private static $laravelServerProcess = null;
|
||||
|
||||
/**
|
||||
* Prepare for Dusk test execution.
|
||||
*/
|
||||
#[BeforeClass]
|
||||
public static function prepare(): void
|
||||
{
|
||||
static::configureDuskBaseUrl();
|
||||
static::ensureLaravelServerIsReachable();
|
||||
|
||||
if (! static::runningInSail()) {
|
||||
static::ensureChromeDriverBinaryAlias();
|
||||
static::startChromeDriver(['--port=9515']);
|
||||
static::waitForChromeDriver();
|
||||
static::waitForTcpPort('127.0.0.1', 9515, 8.0, 'ChromeDriver');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,10 +49,11 @@ abstract class DuskTestCase extends BaseTestCase
|
||||
'--disable-search-engine-choice-screen',
|
||||
'--ignore-certificate-errors',
|
||||
'--allow-insecure-localhost',
|
||||
'--disable-features=Translate,BackForwardCache,AcceptCHFrame',
|
||||
]);
|
||||
|
||||
return RemoteWebDriver::create(
|
||||
$_ENV['DUSK_DRIVER_URL'] ?? 'http://localhost:9515',
|
||||
$_ENV['DUSK_DRIVER_URL'] ?? 'http://127.0.0.1:9515',
|
||||
DesiredCapabilities::chrome()->setCapability(
|
||||
ChromeOptions::CAPABILITY,
|
||||
$options
|
||||
@@ -50,6 +61,108 @@ abstract class DuskTestCase extends BaseTestCase
|
||||
);
|
||||
}
|
||||
|
||||
private static function configureDuskBaseUrl(): void
|
||||
{
|
||||
$url = rtrim((string) ($_ENV['DUSK_APP_URL'] ?? getenv('DUSK_APP_URL') ?: 'http://127.0.0.1:8000'), '/');
|
||||
|
||||
$_ENV['APP_URL'] = $url;
|
||||
$_SERVER['APP_URL'] = $url;
|
||||
putenv('APP_URL='.$url);
|
||||
|
||||
if (property_exists(BaseTestCase::class, 'baseUrl')) {
|
||||
static::$baseUrl = $url;
|
||||
}
|
||||
}
|
||||
|
||||
private static function ensureLaravelServerIsReachable(): void
|
||||
{
|
||||
$url = rtrim((string) ($_ENV['APP_URL'] ?? 'http://127.0.0.1:8000'), '/');
|
||||
$parts = parse_url($url);
|
||||
|
||||
$scheme = $parts['scheme'] ?? 'http';
|
||||
$host = $parts['host'] ?? '127.0.0.1';
|
||||
$port = (int) ($parts['port'] ?? ($scheme === 'https' ? 443 : 80));
|
||||
|
||||
if (static::canConnect($host, $port)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Dusk should be deterministic in local/CI runs. If no reachable app
|
||||
// server is already running, start Laravel's built-in server for the
|
||||
// browser suite instead of failing every test with ERR_CONNECTION_REFUSED.
|
||||
if (! in_array($host, ['127.0.0.1', 'localhost'], true)) {
|
||||
$fallbackUrl = 'http://127.0.0.1:8000';
|
||||
$_ENV['APP_URL'] = $fallbackUrl;
|
||||
$_SERVER['APP_URL'] = $fallbackUrl;
|
||||
putenv('APP_URL='.$fallbackUrl);
|
||||
|
||||
if (property_exists(BaseTestCase::class, 'baseUrl')) {
|
||||
static::$baseUrl = $fallbackUrl;
|
||||
}
|
||||
|
||||
$host = '127.0.0.1';
|
||||
$port = 8000;
|
||||
}
|
||||
|
||||
if (static::canConnect($host, $port)) {
|
||||
return;
|
||||
}
|
||||
|
||||
static::startLaravelServer($host, $port);
|
||||
static::waitForTcpPort($host, $port, 15.0, 'Laravel Dusk application server');
|
||||
}
|
||||
|
||||
private static function startLaravelServer(string $host, int $port): void
|
||||
{
|
||||
$root = dirname(__DIR__);
|
||||
$logPath = $root.'/storage/logs/dusk-server.log';
|
||||
|
||||
if (! is_dir(dirname($logPath))) {
|
||||
@mkdir(dirname($logPath), 0775, true);
|
||||
}
|
||||
|
||||
$php = escapeshellarg(PHP_BINARY);
|
||||
$artisan = escapeshellarg($root.'/artisan');
|
||||
$hostArg = escapeshellarg($host);
|
||||
$portArg = (string) $port;
|
||||
$log = escapeshellarg($logPath);
|
||||
|
||||
$command = "{$php} {$artisan} serve --host={$hostArg} --port={$portArg} > {$log} 2>&1";
|
||||
|
||||
self::$laravelServerProcess = proc_open($command, [], $pipes, $root);
|
||||
}
|
||||
|
||||
private static function canConnect(string $host, int $port): bool
|
||||
{
|
||||
$connection = @fsockopen($host, $port, $errno, $errstr, 0.25);
|
||||
|
||||
if (! is_resource($connection)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
fclose($connection);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static function waitForTcpPort(string $host, int $port, float $seconds, string $service): void
|
||||
{
|
||||
$deadline = microtime(true) + $seconds;
|
||||
|
||||
do {
|
||||
if (static::canConnect($host, $port)) {
|
||||
return;
|
||||
}
|
||||
|
||||
usleep(100_000);
|
||||
} while (microtime(true) < $deadline);
|
||||
|
||||
$log = dirname(__DIR__).'/storage/logs/dusk-server.log';
|
||||
$hint = is_file($log) ? " Check {$log}." : '';
|
||||
|
||||
throw new \RuntimeException("{$service} is not reachable at {$host}:{$port}.{$hint}");
|
||||
}
|
||||
|
||||
/**
|
||||
* Dusk may install a differently named macOS Apple Silicon binary.
|
||||
*
|
||||
@@ -95,24 +208,4 @@ abstract class DuskTestCase extends BaseTestCase
|
||||
@chmod($expected, 0755);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait until ChromeDriver is listening before the first browser session starts.
|
||||
*/
|
||||
private static function waitForChromeDriver(): void
|
||||
{
|
||||
$deadline = microtime(true) + 5.0;
|
||||
|
||||
do {
|
||||
$connection = @fsockopen('127.0.0.1', 9515);
|
||||
|
||||
if (is_resource($connection)) {
|
||||
fclose($connection);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
usleep(100_000);
|
||||
} while (microtime(true) < $deadline);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user