-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
17 changed files
with
816 additions
and
40 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,4 +4,6 @@ | |
/.vagrant | ||
.phpunit.result.cache | ||
.DS_Store | ||
composer.lock | ||
composer.lock | ||
/storage/logs/* | ||
!/storage/logs/.gitkeep |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
<?php | ||
|
||
namespace App\Commands; | ||
|
||
use App\GoogleDownloadable; | ||
|
||
class InstallBrowserCommand extends InstallCommand | ||
{ | ||
protected int $component = GoogleDownloadable::BROWSER; | ||
|
||
protected $name = 'install:browser'; | ||
|
||
/** | ||
* The description of the command. | ||
* | ||
* @var string | ||
*/ | ||
protected $description = 'Install Google Browser'; | ||
|
||
/** | ||
* Execute the console command. | ||
* | ||
* @return mixed | ||
*/ | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
<?php | ||
|
||
namespace App\Commands; | ||
|
||
use App\Facades\GoogleForTesting; | ||
use App\GoogleDownloadable; | ||
use App\OperatingSystem; | ||
use Illuminate\Console\Command; | ||
use Illuminate\Support\Facades\File; | ||
use Illuminate\Support\Facades\Log; | ||
use Illuminate\Support\Str; | ||
use Symfony\Component\Console\Input\InputOption; | ||
|
||
use function Laravel\Prompts\error; | ||
use function Laravel\Prompts\search; | ||
use function Laravel\Prompts\spin; | ||
use function Laravel\Prompts\warning; | ||
use function Termwind\render; | ||
|
||
abstract class InstallCommand extends Command | ||
{ | ||
protected int $component; | ||
|
||
protected array $platforms = [ | ||
'linux' => 'linux64', | ||
'mac-arm' => 'mac-arm64', | ||
'mac-intel' => 'mac-x64', | ||
'win' => 'win64', | ||
]; | ||
|
||
protected function configure(): void | ||
{ | ||
$this->addOption( | ||
'ver', | ||
null, | ||
InputOption::VALUE_OPTIONAL, | ||
'Install a specific version', | ||
'115.0.5763.0', | ||
); | ||
|
||
$this->addOption( | ||
'latest', | ||
null, | ||
InputOption::VALUE_NONE, | ||
'Install the latest version', | ||
); | ||
|
||
$this->addOption( | ||
'path', | ||
null, | ||
InputOption::VALUE_OPTIONAL, | ||
'Specify the path where to download it', | ||
); | ||
} | ||
|
||
public function handle(): int | ||
{ | ||
if (empty($downloadable = $this->version())) { | ||
error("There' no versions available for [{$this->option('ver')}]"); | ||
|
||
return self::FAILURE; | ||
} | ||
|
||
$os = OperatingSystem::id(); | ||
|
||
$version = $downloadable->getVersion(); | ||
|
||
try { | ||
spin( | ||
callback: fn () => $downloadable->download(GoogleDownloadable::BROWSER, $this->getDownloadDirectory(), $this->platforms[$os], true), | ||
message: "Downloading Google Chrome {$this->getComponentName()} [$version]" | ||
); | ||
|
||
$this->message("Google Chrome {$this->getComponentName()} unzip it on [{$this->getDownloadDirectory()}]", 'info'); | ||
} catch (\Throwable $e) { | ||
Log::error($e->getMessage()); | ||
|
||
error("Unable to download/install Google Chrome {$this->getComponentName()} [$version]"); | ||
|
||
return self::FAILURE; | ||
} | ||
|
||
$this->message("Google Chrome {$this->getComponentName()} [$version] downloaded", 'success'); | ||
|
||
return self::SUCCESS; | ||
} | ||
|
||
protected function version(): ?GoogleDownloadable | ||
{ | ||
if ($this->option('latest')) { | ||
return GoogleForTesting::getLatestVersion(); | ||
} | ||
|
||
$version = $this->option('ver'); | ||
|
||
$downloadable = spin( | ||
callback: fn () => GoogleForTesting::getVersion($version), | ||
message: "Searching for version [$version]" | ||
); | ||
|
||
if (filled($downloadable)) { | ||
return $downloadable; | ||
} | ||
|
||
$versions = GoogleForTesting::getMilestone(Str::before($version, '.')); | ||
|
||
if (empty($versions)) { | ||
return null; | ||
} | ||
|
||
warning("There isn't an exact version [$version]"); | ||
|
||
$version = search( | ||
label: 'We found similar versions, please choose one', | ||
options: fn () => $versions->mapWithKeys(fn ($d) => [$d->getVersion() => $d->getVersion()])->all(), | ||
placeholder: 'Choose your prefer version' | ||
); | ||
|
||
return GoogleForTesting::getVersion($version); | ||
} | ||
|
||
protected function getBasePath(string $path = null): string | ||
{ | ||
$folder = join_paths(getenv('HOME'), '.google-for-testing'); | ||
|
||
File::ensureDirectoryExists($folder); | ||
|
||
return join_paths($folder, $path ?? ''); | ||
} | ||
|
||
public function message(string $text, string $type = 'line'): void | ||
{ | ||
$color = match ($type) { | ||
'success' => 'bg-green', | ||
'warning' => 'bg-yellow', | ||
'error' => 'bg-red', | ||
'info' => 'bg-blue', | ||
default => 'bg-gray-600', | ||
}; | ||
|
||
$type = str($type)->upper(); | ||
|
||
render(<<<HTML | ||
<p> | ||
<span class="text-white $color px-2 mr-2">$type</span> | ||
<span>$text</span> | ||
</p> | ||
HTML); | ||
} | ||
|
||
protected function getDownloadDirectory(): string | ||
{ | ||
return $this->option('path') ?? $this->getBasePath(); | ||
} | ||
|
||
protected function getComponent(): int | ||
{ | ||
return $this->component; | ||
} | ||
|
||
protected function getComponentName(): string | ||
{ | ||
return $this->getComponent() === GoogleDownloadable::BROWSER ? 'Browser' : 'Driver'; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
<?php | ||
|
||
namespace App\Commands; | ||
|
||
use App\GoogleDownloadable; | ||
|
||
class InstallDriverCommand extends InstallCommand | ||
{ | ||
protected int $component = GoogleDownloadable::DRIVER; | ||
|
||
protected $name = 'install:driver'; | ||
|
||
/** | ||
* The description of the command. | ||
* | ||
* @var string | ||
*/ | ||
protected $description = 'Install Google Driver'; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<?php | ||
|
||
namespace App\Facades; | ||
|
||
use App\GoogleDownloadable; | ||
use Illuminate\Support\Collection; | ||
use Illuminate\Support\Facades\Facade; | ||
|
||
/** | ||
* @method static null|GoogleDownloadable getLatestVersion() Get the latest version of Google Chrome Browser and Google Chrome Driver | ||
* @method static null|GoogleDownloadable getVersion(string $version) Get a specific version | ||
* @method static null|Collection<GoogleDownloadable> getMilestone(string $version) Get a collection with all the versions available for a Milestone | ||
*/ | ||
class GoogleForTesting extends Facade | ||
{ | ||
public static function getFacadeAccessor(): string | ||
{ | ||
return 'gft'; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
<?php | ||
|
||
namespace App; | ||
|
||
use Illuminate\Support\Str; | ||
|
||
class GoogleDownloadable | ||
{ | ||
const BROWSER = 1; | ||
|
||
const DRIVER = 2; | ||
|
||
protected function __construct( | ||
protected string $version, | ||
protected string $revision, | ||
protected array $browserDownloads, | ||
protected array $driverDownloads | ||
) { | ||
// | ||
} | ||
|
||
public function getVersion(): string | ||
{ | ||
return $this->version; | ||
} | ||
|
||
public function getMilestone(): string | ||
{ | ||
return Str::of($this->version)->before('.'); | ||
} | ||
|
||
/** | ||
* @throws \RuntimeException if the required platform doesn't exist | ||
*/ | ||
public function getChromeBrowserURL(string $platform): string | ||
{ | ||
$item = collect($this->browserDownloads)->first(fn (array $item) => $item['platform'] === $platform); | ||
|
||
if (empty($item)) { | ||
throw new \RuntimeException("The URL for Google Chrome Browser for platform [$platform], it's not available"); | ||
} | ||
|
||
return $item['url']; | ||
} | ||
|
||
/** | ||
* @throws \RuntimeException if the required platform doesn't exist | ||
*/ | ||
public function getChromeDriverURL(string $platform): string | ||
{ | ||
$item = collect($this->driverDownloads)->first(fn (array $item) => $item['platform'] === $platform); | ||
|
||
if (empty($item)) { | ||
throw new \RuntimeException("The URL for Google Chrome Driver for platform [$platform], it's not available"); | ||
} | ||
|
||
return $item['url']; | ||
} | ||
|
||
public function download(int $component, string $to, string $platform, bool $unzip = false): void | ||
{ | ||
if ($component & static::BROWSER) { | ||
$url = $this->getChromeBrowserURL($platform); | ||
$filename = join_paths($to, Str::afterLast($url, '/')); | ||
|
||
download($url, $filename); | ||
|
||
$unzip && unzip($filename); | ||
} | ||
|
||
if ($component & static::DRIVER) { | ||
$url = $this->getChromeDriverURL($platform); | ||
$filename = join_paths($to, Str::afterLast($url, '/')); | ||
|
||
download($url, $filename); | ||
|
||
$unzip && unzip($filename); | ||
} | ||
} | ||
|
||
public static function make(string $version, string $revision, array $browserDownloads, array $driverDownloads): static | ||
{ | ||
return new static($version, $revision, $browserDownloads, $driverDownloads); | ||
} | ||
|
||
public static function makeFromArray(array $data): static | ||
{ | ||
$downloads = $data['downloads']; | ||
|
||
$version = $data['version']; | ||
$revision = $data['revision']; | ||
$browserDownloads = $downloads['chrome']; | ||
$driverDownloads = $downloads['chromedriver'] ?? []; | ||
|
||
return static::make($version, $revision, $browserDownloads, $driverDownloads); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
<?php | ||
|
||
namespace App; | ||
|
||
use Illuminate\Support\Collection; | ||
use Illuminate\Support\Facades\Http; | ||
use Illuminate\Support\Str; | ||
|
||
class GoogleForTesting | ||
{ | ||
protected static string $started = '115.0.5763.0'; | ||
|
||
protected static string $latest = 'https://googlechromelabs.github.io/chrome-for-testing/last-known-good-versions.json'; | ||
|
||
protected static string $versions = 'https://googlechromelabs.github.io/chrome-for-testing/known-good-versions.json'; | ||
|
||
protected static string $downloads = 'https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json'; | ||
|
||
public function getLatestVersion(): ?GoogleDownloadable | ||
{ | ||
$response = Http::get(static::$latest); | ||
|
||
$channel = $response->json('channels')['Stable']; | ||
|
||
$version = $channel['version']; | ||
|
||
return static::getVersion($version); | ||
} | ||
|
||
public function getVersion(string $version): ?GoogleDownloadable | ||
{ | ||
$response = Http::get(static::$downloads); | ||
|
||
$exact = collect($response->json('versions')) | ||
->first(fn (array $item) => $item['version'] == $version); | ||
|
||
if (empty($exact)) { | ||
return null; | ||
} | ||
|
||
return GoogleDownloadable::makeFromArray($exact); | ||
} | ||
|
||
public function getMilestone(string $milestone): ?Collection | ||
{ | ||
$response = Http::get(static::$downloads); | ||
|
||
$versions = collect($response->json('versions')) | ||
->filter(fn (array $item) => Str::before($item['version'], '.') == $milestone) | ||
->map(fn (array $version) => GoogleDownloadable::makeFromArray($version)); | ||
|
||
if ($versions->isEmpty()) { | ||
return null; | ||
} | ||
|
||
return $versions; | ||
} | ||
} |
Oops, something went wrong.