feat: allow installing chrome/chromedriver by milestone and version prefix (#10720)

This commit is contained in:
Alex Rudenko 2023-08-10 13:00:22 +02:00 committed by GitHub
parent 0c59e9a1cb
commit bec2357aee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 136 additions and 48 deletions

View File

@ -132,6 +132,26 @@ export class CLI {
'$0 install chrome@latest',
'Install the latest available build for the Chrome browser.'
);
yargs.example(
'$0 install chrome@canary',
'Install the latest available build for the Chrome Canary browser.'
);
yargs.example(
'$0 install chrome@115',
'Install the latest available build for Chrome 115.'
);
yargs.example(
'$0 install chromedriver@canary',
'Install the latest available build for ChromeDriver Canary.'
);
yargs.example(
'$0 install chromedriver@115',
'Install the latest available build for ChromeDriver 115.'
);
yargs.example(
'$0 install chromedriver@115.0.5790',
'Install the latest available patch (115.0.5790.X) build for ChromeDriver.'
);
yargs.example(
'$0 install chromium@1083080',
'Install the revision 1083080 of the Chromium browser.'
@ -201,15 +221,15 @@ export class CLI {
default: false,
});
yargs.example(
'$0 launch chrome@1083080',
'Launch the Chrome browser identified by the revision 1083080.'
'$0 launch chrome@115.0.5790.170',
'Launch Chrome 115.0.5790.170'
);
yargs.example(
'$0 launch firefox@112.0a1',
'Launch the Firefox browser identified by the milestone 112.0a1.'
);
yargs.example(
'$0 launch chrome@1083080 --detached',
'$0 launch chrome@115.0.5790.170 --detached',
'Launch the browser but detach the sub-processes.'
);
yargs.example(

View File

@ -72,36 +72,28 @@ export async function resolveBuildId(
`${tag} is not supported for ${browser}. Use 'latest' instead.`
);
}
case Browser.CHROME:
case Browser.CHROME: {
switch (tag as BrowserTag) {
case BrowserTag.LATEST:
return await chrome.resolveBuildId(
platform,
ChromeReleaseChannel.CANARY
);
return await chrome.resolveBuildId(ChromeReleaseChannel.CANARY);
case BrowserTag.BETA:
return await chrome.resolveBuildId(
platform,
ChromeReleaseChannel.BETA
);
return await chrome.resolveBuildId(ChromeReleaseChannel.BETA);
case BrowserTag.CANARY:
return await chrome.resolveBuildId(
platform,
ChromeReleaseChannel.CANARY
);
return await chrome.resolveBuildId(ChromeReleaseChannel.CANARY);
case BrowserTag.DEV:
return await chrome.resolveBuildId(
platform,
ChromeReleaseChannel.DEV
);
return await chrome.resolveBuildId(ChromeReleaseChannel.DEV);
case BrowserTag.STABLE:
return await chrome.resolveBuildId(
platform,
ChromeReleaseChannel.STABLE
);
return await chrome.resolveBuildId(ChromeReleaseChannel.STABLE);
default:
const result = await chrome.resolveBuildId(tag);
if (result) {
return result;
}
}
case Browser.CHROMEDRIVER:
switch (tag as BrowserTag) {
return tag;
}
case Browser.CHROMEDRIVER: {
switch (tag) {
case BrowserTag.LATEST:
case BrowserTag.CANARY:
return await chromedriver.resolveBuildId(ChromeReleaseChannel.CANARY);
@ -111,7 +103,14 @@ export async function resolveBuildId(
return await chromedriver.resolveBuildId(ChromeReleaseChannel.DEV);
case BrowserTag.STABLE:
return await chromedriver.resolveBuildId(ChromeReleaseChannel.STABLE);
default:
const result = await chromedriver.resolveBuildId(tag);
if (result) {
return result;
}
}
return tag;
}
case Browser.CHROMIUM:
switch (tag as BrowserTag) {
case BrowserTag.LATEST:

View File

@ -97,11 +97,66 @@ export async function getLastKnownGoodReleaseForChannel(
).channels[channel];
}
export async function getLastKnownGoodReleaseForMilestone(
milestone: string
): Promise<{version: string; revision: string} | undefined> {
const data = (await getJSON(
new URL(
'https://googlechromelabs.github.io/chrome-for-testing/latest-versions-per-milestone.json'
)
)) as {
milestones: Record<string, {version: string; revision: string}>;
};
return data.milestones[milestone] as
| {version: string; revision: string}
| undefined;
}
export async function getLastKnownGoodReleaseForBuild(
/**
* @example `112.0.23`,
*/
buildPrefix: string
): Promise<{version: string; revision: string} | undefined> {
const data = (await getJSON(
new URL(
'https://googlechromelabs.github.io/chrome-for-testing/latest-patch-versions-per-build.json'
)
)) as {
builds: Record<string, {version: string; revision: string}>;
};
return data.builds[buildPrefix] as
| {version: string; revision: string}
| undefined;
}
export async function resolveBuildId(
_platform: BrowserPlatform,
channel: ChromeReleaseChannel
): Promise<string> {
return (await getLastKnownGoodReleaseForChannel(channel)).version;
): Promise<string>;
export async function resolveBuildId(
channel: string
): Promise<string | undefined>;
export async function resolveBuildId(
channel: ChromeReleaseChannel | string
): Promise<string | undefined> {
if (
Object.values(ChromeReleaseChannel).includes(
channel as ChromeReleaseChannel
)
) {
return (
await getLastKnownGoodReleaseForChannel(channel as ChromeReleaseChannel)
).version;
}
if (channel.match(/^\d+$/)) {
// Potentially a milestone.
return (await getLastKnownGoodReleaseForMilestone(channel))?.version;
}
if (channel.match(/^\d+\.\d+\.\d+$/)) {
// Potentially a build prefix without the patch version.
return (await getLastKnownGoodReleaseForBuild(channel))?.version;
}
return;
}
export function resolveSystemExecutablePath(

View File

@ -15,8 +15,7 @@
*/
import path from 'path';
import {getLastKnownGoodReleaseForChannel} from './chrome.js';
import {BrowserPlatform, ChromeReleaseChannel} from './types.js';
import {BrowserPlatform} from './types.js';
function folder(platform: BrowserPlatform): string {
switch (platform) {
@ -63,8 +62,5 @@ export function relativeExecutablePath(
return path.join('chromedriver-' + folder(platform), 'chromedriver.exe');
}
}
export async function resolveBuildId(
channel: ChromeReleaseChannel
): Promise<string> {
return (await getLastKnownGoodReleaseForChannel(channel)).version;
}
export {resolveBuildId} from './chrome.js';

View File

@ -25,6 +25,7 @@ import {
resolveDownloadUrl,
relativeExecutablePath,
resolveSystemExecutablePath,
resolveBuildId,
} from '../../../lib/cjs/browser-data/chrome.js';
describe('Chrome', () => {
@ -117,4 +118,12 @@ describe('Chrome', () => {
);
}, new Error(`Unable to detect browser executable path for 'canary' on linux.`));
});
it('should resolve milestones', async () => {
assert.strictEqual(await resolveBuildId('115'), '115.0.5790.170');
});
it('should resolve build prefix', async () => {
assert.strictEqual(await resolveBuildId('115.0.5790'), '115.0.5790.170');
});
});

View File

@ -21,6 +21,7 @@ import {BrowserPlatform} from '../../../lib/cjs/browser-data/browser-data.js';
import {
resolveDownloadUrl,
relativeExecutablePath,
resolveBuildId,
} from '../../../lib/cjs/browser-data/chromedriver.js';
describe('ChromeDriver', () => {
@ -47,6 +48,14 @@ describe('ChromeDriver', () => {
);
});
it('should resolve milestones', async () => {
assert.strictEqual(await resolveBuildId('115'), '115.0.5790.170');
});
it('should resolve build prefix', async () => {
assert.strictEqual(await resolveBuildId('115.0.5790'), '115.0.5790.170');
});
it('should resolve executable paths', () => {
assert.strictEqual(
relativeExecutablePath(BrowserPlatform.LINUX, '12372323'),

View File

@ -689,6 +689,18 @@
"parameters": ["cdp", "firefox"],
"expectations": ["SKIP"]
},
{
"testIdPattern": "[evaluation.spec] Evaluation specs Page.evaluateOnNewDocument should evaluate before anything else on the page",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["webDriverBiDi"],
"expectations": ["PASS"]
},
{
"testIdPattern": "[evaluation.spec] Evaluation specs Page.evaluateOnNewDocument should work with CSP",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["webDriverBiDi"],
"expectations": ["PASS"]
},
{
"testIdPattern": "[evaluation.spec] Evaluation specs Page.removeScriptToEvaluateOnNewDocument *",
"platforms": ["darwin", "linux", "win32"],
@ -4150,17 +4162,5 @@
"platforms": ["darwin", "linux", "win32"],
"parameters": ["cdp", "chrome", "headless"],
"expectations": ["FAIL", "PASS"]
},
{
"testIdPattern": "[evaluation.spec] Evaluation specs Page.evaluateOnNewDocument should evaluate before anything else on the page",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["webDriverBiDi"],
"expectations": ["PASS"]
},
{
"testIdPattern": "[evaluation.spec] Evaluation specs Page.evaluateOnNewDocument should work with CSP",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["webDriverBiDi"],
"expectations": ["PASS"]
}
]