mirror of
https://github.com/puppeteer/puppeteer
synced 2024-06-14 14:02:48 +00:00
feat: support stable/dev/beta/canary keywords for chrome and chromium (#10140)
This commit is contained in:
parent
baf2a86fdd
commit
90ed263eaf
@ -24,7 +24,7 @@ npx @puppeteer/browsers launch --help # help for the launch command
|
||||
|
||||
## Known limitations
|
||||
|
||||
1. We support installing and running Firefox and Chrome/Chromium. The `latest` keyword only works during the installation. For the `launch` command you need to specify an exact build ID. The build ID is provided by the `install` command (see `npx @puppeteer/browsers install --help` for the format).
|
||||
1. We support installing and running Firefox, Chrome and Chromium. The `latest`, `beta`, `dev`, `canary`, `stable` keywords are only supported for the install command. For the `launch` command you need to specify an exact build ID. The build ID is provided by the `install` command (see `npx @puppeteer/browsers install --help` for the format).
|
||||
2. Launching the system browsers is only possible for Chrome/Chromium.
|
||||
|
||||
## API
|
||||
|
@ -20,7 +20,7 @@ npx @puppeteer/browsers launch --help # help for the launch command
|
||||
|
||||
## Known limitations
|
||||
|
||||
1. We support installing and running Firefox and Chrome/Chromium. The `latest` keyword only works during the installation. For the `launch` command you need to specify an exact build ID. The build ID is provided by the `install` command (see `npx @puppeteer/browsers install --help` for the format).
|
||||
1. We support installing and running Firefox, Chrome and Chromium. The `latest`, `beta`, `dev`, `canary`, `stable` keywords are only supported for the install command. For the `launch` command you need to specify an exact build ID. The build ID is provided by the `install` command (see `npx @puppeteer/browsers install --help` for the format).
|
||||
2. Launching the system browsers is only possible for Chrome/Chromium.
|
||||
|
||||
## API
|
||||
|
@ -64,22 +64,74 @@ export async function resolveBuildId(
|
||||
switch (tag as BrowserTag) {
|
||||
case BrowserTag.LATEST:
|
||||
return await firefox.resolveBuildId('FIREFOX_NIGHTLY');
|
||||
case BrowserTag.BETA:
|
||||
case BrowserTag.CANARY:
|
||||
case BrowserTag.DEV:
|
||||
case BrowserTag.STABLE:
|
||||
throw new Error(`${tag} is not supported for ${browser}`);
|
||||
}
|
||||
case Browser.CHROME:
|
||||
switch (tag as BrowserTag) {
|
||||
case BrowserTag.LATEST:
|
||||
// In CfT beta is the latest version.
|
||||
return await chrome.resolveBuildId(platform, 'beta');
|
||||
return await chrome.resolveBuildId(
|
||||
platform,
|
||||
ChromeReleaseChannel.CANARY
|
||||
);
|
||||
case BrowserTag.BETA:
|
||||
return await chrome.resolveBuildId(
|
||||
platform,
|
||||
ChromeReleaseChannel.BETA
|
||||
);
|
||||
case BrowserTag.CANARY:
|
||||
return await chrome.resolveBuildId(
|
||||
platform,
|
||||
ChromeReleaseChannel.CANARY
|
||||
);
|
||||
case BrowserTag.DEV:
|
||||
return await chrome.resolveBuildId(
|
||||
platform,
|
||||
ChromeReleaseChannel.DEV
|
||||
);
|
||||
case BrowserTag.STABLE:
|
||||
return await chrome.resolveBuildId(
|
||||
platform,
|
||||
ChromeReleaseChannel.STABLE
|
||||
);
|
||||
}
|
||||
case Browser.CHROMEDRIVER:
|
||||
switch (tag as BrowserTag) {
|
||||
case BrowserTag.LATEST:
|
||||
return await chromedriver.resolveBuildId('latest');
|
||||
case BrowserTag.BETA:
|
||||
case BrowserTag.CANARY:
|
||||
case BrowserTag.DEV:
|
||||
case BrowserTag.STABLE:
|
||||
throw new Error(`${tag} is not support for ${browser}`);
|
||||
}
|
||||
case Browser.CHROMIUM:
|
||||
switch (tag as BrowserTag) {
|
||||
case BrowserTag.LATEST:
|
||||
return await chromium.resolveBuildId(platform, 'latest');
|
||||
case BrowserTag.BETA:
|
||||
return await chromium.resolveBuildId(
|
||||
platform,
|
||||
ChromeReleaseChannel.BETA
|
||||
);
|
||||
case BrowserTag.CANARY:
|
||||
return await chromium.resolveBuildId(
|
||||
platform,
|
||||
ChromeReleaseChannel.CANARY
|
||||
);
|
||||
case BrowserTag.DEV:
|
||||
return await chromium.resolveBuildId(
|
||||
platform,
|
||||
ChromeReleaseChannel.DEV
|
||||
);
|
||||
case BrowserTag.STABLE:
|
||||
return await chromium.resolveBuildId(
|
||||
platform,
|
||||
ChromeReleaseChannel.STABLE
|
||||
);
|
||||
}
|
||||
}
|
||||
// We assume the tag is the buildId if it didn't match any keywords.
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
import path from 'path';
|
||||
|
||||
import {httpRequest} from '../httpUtil.js';
|
||||
import {getJSON} from '../httpUtil.js';
|
||||
|
||||
import {BrowserPlatform, ChromeReleaseChannel} from './types.js';
|
||||
|
||||
@ -35,21 +35,6 @@ function folder(platform: BrowserPlatform): string {
|
||||
}
|
||||
}
|
||||
|
||||
function chromiumDashPlatform(platform: BrowserPlatform): string {
|
||||
switch (platform) {
|
||||
case BrowserPlatform.LINUX:
|
||||
return 'linux';
|
||||
case BrowserPlatform.MAC_ARM:
|
||||
return 'mac';
|
||||
case BrowserPlatform.MAC:
|
||||
return 'mac';
|
||||
case BrowserPlatform.WIN32:
|
||||
return 'win';
|
||||
case BrowserPlatform.WIN64:
|
||||
return 'win64';
|
||||
}
|
||||
}
|
||||
|
||||
export function resolveDownloadUrl(
|
||||
platform: BrowserPlatform,
|
||||
buildId: string,
|
||||
@ -86,41 +71,39 @@ export function relativeExecutablePath(
|
||||
return path.join('chrome-' + folder(platform), 'chrome.exe');
|
||||
}
|
||||
}
|
||||
|
||||
export async function getLastKnownGoodReleaseForChannel(
|
||||
channel: ChromeReleaseChannel
|
||||
): Promise<{version: string; revision: string}> {
|
||||
const data = (await getJSON(
|
||||
new URL(
|
||||
'https://googlechromelabs.github.io/chrome-for-testing/last-known-good-versions.json'
|
||||
)
|
||||
)) as {
|
||||
channels: {
|
||||
[channel: string]: {version: string};
|
||||
};
|
||||
};
|
||||
|
||||
for (const channel of Object.keys(data.channels)) {
|
||||
data.channels[channel.toLowerCase()] = data.channels[channel]!;
|
||||
delete data.channels[channel];
|
||||
}
|
||||
|
||||
return (
|
||||
data as {
|
||||
channels: {
|
||||
[channel in ChromeReleaseChannel]: {version: string; revision: string};
|
||||
};
|
||||
}
|
||||
).channels[channel];
|
||||
}
|
||||
|
||||
export async function resolveBuildId(
|
||||
platform: BrowserPlatform,
|
||||
channel: 'beta' | 'stable' = 'beta'
|
||||
_platform: BrowserPlatform,
|
||||
channel: ChromeReleaseChannel
|
||||
): Promise<string> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const request = httpRequest(
|
||||
new URL(
|
||||
`https://chromiumdash.appspot.com/fetch_releases?platform=${chromiumDashPlatform(
|
||||
platform
|
||||
)}&channel=${channel}`
|
||||
),
|
||||
'GET',
|
||||
response => {
|
||||
let data = '';
|
||||
if (response.statusCode && response.statusCode >= 400) {
|
||||
return reject(new Error(`Got status code ${response.statusCode}`));
|
||||
}
|
||||
response.on('data', chunk => {
|
||||
data += chunk;
|
||||
});
|
||||
response.on('end', () => {
|
||||
try {
|
||||
const response = JSON.parse(String(data));
|
||||
return resolve(response[0].version);
|
||||
} catch {
|
||||
return reject(new Error('Chrome version not found'));
|
||||
}
|
||||
});
|
||||
},
|
||||
false
|
||||
);
|
||||
request.on('error', err => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
return (await getLastKnownGoodReleaseForChannel(channel)).version;
|
||||
}
|
||||
|
||||
export function resolveSystemExecutablePath(
|
||||
|
@ -16,9 +16,10 @@
|
||||
|
||||
import path from 'path';
|
||||
|
||||
import {httpRequest} from '../httpUtil.js';
|
||||
import {getText} from '../httpUtil.js';
|
||||
|
||||
import {BrowserPlatform} from './types.js';
|
||||
import {getLastKnownGoodReleaseForChannel} from './chrome.js';
|
||||
import {BrowserPlatform, ChromeReleaseChannel} from './types.js';
|
||||
|
||||
export {resolveSystemExecutablePath} from './chrome.js';
|
||||
|
||||
@ -89,37 +90,16 @@ export function relativeExecutablePath(
|
||||
}
|
||||
export async function resolveBuildId(
|
||||
platform: BrowserPlatform,
|
||||
// We will need it for other channels/keywords.
|
||||
_channel: 'latest' = 'latest'
|
||||
channel: ChromeReleaseChannel | 'latest' = 'latest'
|
||||
): Promise<string> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const request = httpRequest(
|
||||
if (channel === 'latest') {
|
||||
return await getText(
|
||||
new URL(
|
||||
`https://storage.googleapis.com/chromium-browser-snapshots/${folder(
|
||||
platform
|
||||
)}/LAST_CHANGE`
|
||||
),
|
||||
'GET',
|
||||
response => {
|
||||
let data = '';
|
||||
if (response.statusCode && response.statusCode >= 400) {
|
||||
return reject(new Error(`Got status code ${response.statusCode}`));
|
||||
}
|
||||
response.on('data', chunk => {
|
||||
data += chunk;
|
||||
});
|
||||
response.on('end', () => {
|
||||
try {
|
||||
return resolve(String(data));
|
||||
} catch {
|
||||
return reject(new Error('Chrome version not found'));
|
||||
}
|
||||
});
|
||||
},
|
||||
false
|
||||
)
|
||||
);
|
||||
request.on('error', err => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
return (await getLastKnownGoodReleaseForChannel(channel)).revision;
|
||||
}
|
||||
|
@ -53,6 +53,10 @@ export const downloadUrls = {
|
||||
* @public
|
||||
*/
|
||||
export enum BrowserTag {
|
||||
CANARY = 'canary',
|
||||
BETA = 'beta',
|
||||
DEV = 'dev',
|
||||
STABLE = 'stable',
|
||||
LATEST = 'latest',
|
||||
}
|
||||
|
||||
|
@ -135,3 +135,41 @@ export function downloadFile(
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export async function getJSON(url: URL): Promise<unknown> {
|
||||
const text = await getText(url);
|
||||
try {
|
||||
return JSON.parse(text);
|
||||
} catch {
|
||||
throw new Error('Could not parse JSON from ' + url.toString());
|
||||
}
|
||||
}
|
||||
|
||||
export function getText(url: URL): Promise<string> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const request = httpRequest(
|
||||
url,
|
||||
'GET',
|
||||
response => {
|
||||
let data = '';
|
||||
if (response.statusCode && response.statusCode >= 400) {
|
||||
return reject(new Error(`Got status code ${response.statusCode}`));
|
||||
}
|
||||
response.on('data', chunk => {
|
||||
data += chunk;
|
||||
});
|
||||
response.on('end', () => {
|
||||
try {
|
||||
return resolve(String(data));
|
||||
} catch {
|
||||
return reject(new Error('Chrome version not found'));
|
||||
}
|
||||
});
|
||||
},
|
||||
false
|
||||
);
|
||||
request.on('error', err => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -425,6 +425,30 @@
|
||||
"parameters": ["webDriverBiDi"],
|
||||
"expectations": ["PASS"]
|
||||
},
|
||||
{
|
||||
"testIdPattern": "[page.spec] Page Page.setContent should work with accents",
|
||||
"platforms": ["darwin", "linux", "win32"],
|
||||
"parameters": ["webDriverBiDi"],
|
||||
"expectations": ["FAIL"]
|
||||
},
|
||||
{
|
||||
"testIdPattern": "[page.spec] Page Page.setContent should work with emojis",
|
||||
"platforms": ["darwin", "linux", "win32"],
|
||||
"parameters": ["webDriverBiDi"],
|
||||
"expectations": ["FAIL"]
|
||||
},
|
||||
{
|
||||
"testIdPattern": "[page.spec] Page Page.setContent should work with newline",
|
||||
"platforms": ["darwin", "linux", "win32"],
|
||||
"parameters": ["webDriverBiDi"],
|
||||
"expectations": ["FAIL"]
|
||||
},
|
||||
{
|
||||
"testIdPattern": "[page.spec] Page Page.setContent should work with tricky content",
|
||||
"platforms": ["darwin", "linux", "win32"],
|
||||
"parameters": ["webDriverBiDi"],
|
||||
"expectations": ["FAIL"]
|
||||
},
|
||||
{
|
||||
"testIdPattern": "[proxy.spec] *",
|
||||
"platforms": ["darwin", "linux", "win32"],
|
||||
@ -1769,30 +1793,6 @@
|
||||
"parameters": ["cdp", "firefox"],
|
||||
"expectations": ["FAIL"]
|
||||
},
|
||||
{
|
||||
"testIdPattern": "[page.spec] Page Page.setContent should work with accents",
|
||||
"platforms": ["darwin", "linux", "win32"],
|
||||
"parameters": ["webDriverBiDi"],
|
||||
"expectations": ["FAIL"]
|
||||
},
|
||||
{
|
||||
"testIdPattern": "[page.spec] Page Page.setContent should work with emojis",
|
||||
"platforms": ["darwin", "linux", "win32"],
|
||||
"parameters": ["webDriverBiDi"],
|
||||
"expectations": ["FAIL"]
|
||||
},
|
||||
{
|
||||
"testIdPattern": "[page.spec] Page Page.setContent should work with newline",
|
||||
"platforms": ["darwin", "linux", "win32"],
|
||||
"parameters": ["webDriverBiDi"],
|
||||
"expectations": ["FAIL"]
|
||||
},
|
||||
{
|
||||
"testIdPattern": "[page.spec] Page Page.setContent should work with tricky content",
|
||||
"platforms": ["darwin", "linux", "win32"],
|
||||
"parameters": ["webDriverBiDi"],
|
||||
"expectations": ["FAIL"]
|
||||
},
|
||||
{
|
||||
"testIdPattern": "[page.spec] Page Page.setGeolocation should work",
|
||||
"platforms": ["darwin", "linux", "win32"],
|
||||
|
Loading…
Reference in New Issue
Block a user