Skip to content

Commit

Permalink
Bugfix/#92 fix chromedriver latest version detection using outdated a…
Browse files Browse the repository at this point in the history
…pi (#93)

* bugfix: Update const to clearly refer to legacy endpoint

* bugfix: Base the latest version on the new endpoint

* bugfix: Update test

* bugfix: Add fetching of the latest beta version, as the functionality to downscale to the last beta when using Dev or Canary was lost during the transition to the json endpoints
  • Loading branch information
KevinVanSonsbeek authored Feb 20, 2024
1 parent 32488d5 commit 2628c95
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 13 deletions.
41 changes: 32 additions & 9 deletions src/Driver/ChromeDriver/VersionResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
final class VersionResolver implements VersionResolverInterface
{
public const MAJOR_VERSION_ENDPOINT_BREAKPOINT = 115;
private const VERSION_ENDPOINT = 'https://chromedriver.storage.googleapis.com/LATEST_RELEASE';
private const LEGACY_ENDPOINT = 'https://chromedriver.storage.googleapis.com/LATEST_RELEASE';
private const LATEST_VERSION_ENDPOINT_JSON = 'https://googlechromelabs.github.io/chrome-for-testing/last-known-good-versions.json';
private const VERSION_ENDPOINT_JSON = 'https://googlechromelabs.github.io/chrome-for-testing/latest-patch-versions-per-build.json';

private HttpClientInterface $httpClient;
Expand Down Expand Up @@ -68,10 +69,13 @@ public function fromBrowser(Browser $browser): Version

public function latest(): Version
{
$response = $this->httpClient->request('GET', self::VERSION_ENDPOINT);
$versionString = $response->getContent();
$response = $this->httpClient->request('GET', self::LATEST_VERSION_ENDPOINT_JSON);
$versions = $response->toArray();
if (! isset($versions['channels']['Stable']['version'])) {
throw new UnexpectedValueException('Could not resolve the latest stable version.');
}

return Version::fromString($versionString);
return Version::fromString((string) $versions['channels']['Stable']['version']);
}

public function supports(Browser $browser): bool
Expand All @@ -81,6 +85,17 @@ public function supports(Browser $browser): bool
return $browserName->equals(BrowserName::GOOGLE_CHROME()) || $browserName->equals(BrowserName::CHROMIUM());
}

private function latestBetaVersion(): Version
{
$response = $this->httpClient->request('GET', self::LATEST_VERSION_ENDPOINT_JSON);
$versions = $response->toArray();
if (! isset($versions['channels']['Beta']['version'])) {
throw new UnexpectedValueException('Could not resolve the latest beta version.');
}

return Version::fromString((string) $versions['channels']['Beta']['version']);
}

/**
* @throws RedirectionExceptionInterface
* @throws ClientExceptionInterface
Expand All @@ -95,27 +110,35 @@ private function getVersionString(Browser $browser): string

$response = $this->httpClient->request('GET', self::VERSION_ENDPOINT_JSON);
$versions = $response->toArray();
if (! array_key_exists($browser->version()->toString(), $versions['builds'])) {

$latestBeta = $this->latestBetaVersion();
$versionToFetch = $browser->version();
if ((int) $versionToFetch->major() > (int) $latestBeta->major()) {
// In this case we're dealing with a Dev or Canary version, so we will take the last Beta version.
$versionToFetch = $latestBeta;
}

if (! array_key_exists($versionToFetch->toString(), $versions['builds'])) {
throw new UnexpectedValueException(
sprintf('There is no build for version : %s', $browser->version()->toString())
sprintf('There is no build for version : %s', $versionToFetch->toString())
);
}

return $versions['builds'][$browser->version()->toString()]['version'];
return $versions['builds'][$versionToFetch->toString()]['version'];
}

/**
* In case of handling with Chrome from Dev or Canary channel we will then take beta ChromeDriver
*/
private function getBrowserVersionEndpoint(Browser $browser): string
{
$versionEndpoint = sprintf('%s_%s', self::VERSION_ENDPOINT, $browser->version()->toString());
$versionEndpoint = sprintf('%s_%s', self::LEGACY_ENDPOINT, $browser->version()->toString());

$stableVersion = $this->latest();
$betaVersionMajor = (int) $stableVersion->major() + 1;

if ((int) $browser->version()->major() > $betaVersionMajor) {
$versionEndpoint = sprintf('%s_%s', self::VERSION_ENDPOINT, (string) $betaVersionMajor);
$versionEndpoint = sprintf('%s_%s', self::LEGACY_ENDPOINT, (string) $betaVersionMajor);
}

return $versionEndpoint;
Expand Down
24 changes: 20 additions & 4 deletions tests/Driver/ChromeDriver/VersionResolverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,14 @@ public function testFromExceptionIfCanNotParseVersionReceived(): void

public function testFromGetBetaVersionForDevChrome(): void
{
$devChrome = new Browser(BrowserName::GOOGLE_CHROME(), Version::fromString('88.0.4302.0'), OperatingSystem::MACOS());
$devChrome = new Browser(BrowserName::GOOGLE_CHROME(), Version::fromString('123.0.6300.3'), OperatingSystem::MACOS());

self::assertEquals(Version::fromString('87.0.4280.20'), $this->versionResolver->fromBrowser($devChrome));
self::assertEquals(Version::fromString('122.0.6261.39'), $this->versionResolver->fromBrowser($devChrome));
}

public function testLatest(): void
{
self::assertEquals(Version::fromString('86.0.4240.22'), $this->versionResolver->latest());
self::assertEquals(Version::fromString('121.0.6167.184'), $this->versionResolver->latest());
}

protected function setUp(): void
Expand All @@ -99,9 +99,25 @@ static function (string $method, string $url): MockResponse {
return new MockResponse('87.0.4280.20');
}

if ($url === 'https://googlechromelabs.github.io/chrome-for-testing/last-known-good-versions.json') {
return new MockResponse(
json_encode([
'channels' => [
'Stable' => ['version' => '121.0.6167.184'],
'Beta' => ['version' => '122.0.6261.39'],
],
])
);
}

if ($url === 'https://googlechromelabs.github.io/chrome-for-testing/latest-patch-versions-per-build.json') {
return new MockResponse(
json_encode(['builds' => ['115.0.5751' => ['version' => '115.0.5751.20']]])
json_encode([
'builds' => [
'115.0.5751' => ['version' => '115.0.5751.20'],
'122.0.6261' => ['version' => '122.0.6261.39'],
],
])
);
}
}
Expand Down

0 comments on commit 2628c95

Please sign in to comment.