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
|
## 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.
|
2. Launching the system browsers is only possible for Chrome/Chromium.
|
||||||
|
|
||||||
## API
|
## API
|
||||||
|
@ -20,7 +20,7 @@ npx @puppeteer/browsers launch --help # help for the launch command
|
|||||||
|
|
||||||
## Known limitations
|
## 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.
|
2. Launching the system browsers is only possible for Chrome/Chromium.
|
||||||
|
|
||||||
## API
|
## API
|
||||||
|
@ -64,22 +64,74 @@ export async function resolveBuildId(
|
|||||||
switch (tag as BrowserTag) {
|
switch (tag as BrowserTag) {
|
||||||
case BrowserTag.LATEST:
|
case BrowserTag.LATEST:
|
||||||
return await firefox.resolveBuildId('FIREFOX_NIGHTLY');
|
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:
|
case Browser.CHROME:
|
||||||
switch (tag as BrowserTag) {
|
switch (tag as BrowserTag) {
|
||||||
case BrowserTag.LATEST:
|
case BrowserTag.LATEST:
|
||||||
// In CfT beta is the latest version.
|
return await chrome.resolveBuildId(
|
||||||
return await chrome.resolveBuildId(platform, 'beta');
|
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:
|
case Browser.CHROMEDRIVER:
|
||||||
switch (tag as BrowserTag) {
|
switch (tag as BrowserTag) {
|
||||||
case BrowserTag.LATEST:
|
case BrowserTag.LATEST:
|
||||||
return await chromedriver.resolveBuildId('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:
|
case Browser.CHROMIUM:
|
||||||
switch (tag as BrowserTag) {
|
switch (tag as BrowserTag) {
|
||||||
case BrowserTag.LATEST:
|
case BrowserTag.LATEST:
|
||||||
return await chromium.resolveBuildId(platform, '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.
|
// We assume the tag is the buildId if it didn't match any keywords.
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
|
|
||||||
import {httpRequest} from '../httpUtil.js';
|
import {getJSON} from '../httpUtil.js';
|
||||||
|
|
||||||
import {BrowserPlatform, ChromeReleaseChannel} from './types.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(
|
export function resolveDownloadUrl(
|
||||||
platform: BrowserPlatform,
|
platform: BrowserPlatform,
|
||||||
buildId: string,
|
buildId: string,
|
||||||
@ -86,41 +71,39 @@ export function relativeExecutablePath(
|
|||||||
return path.join('chrome-' + folder(platform), 'chrome.exe');
|
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(
|
export async function resolveBuildId(
|
||||||
platform: BrowserPlatform,
|
_platform: BrowserPlatform,
|
||||||
channel: 'beta' | 'stable' = 'beta'
|
channel: ChromeReleaseChannel
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
return new Promise((resolve, reject) => {
|
return (await getLastKnownGoodReleaseForChannel(channel)).version;
|
||||||
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);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function resolveSystemExecutablePath(
|
export function resolveSystemExecutablePath(
|
||||||
|
@ -16,9 +16,10 @@
|
|||||||
|
|
||||||
import path from 'path';
|
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';
|
export {resolveSystemExecutablePath} from './chrome.js';
|
||||||
|
|
||||||
@ -89,37 +90,16 @@ export function relativeExecutablePath(
|
|||||||
}
|
}
|
||||||
export async function resolveBuildId(
|
export async function resolveBuildId(
|
||||||
platform: BrowserPlatform,
|
platform: BrowserPlatform,
|
||||||
// We will need it for other channels/keywords.
|
channel: ChromeReleaseChannel | 'latest' = 'latest'
|
||||||
_channel: 'latest' = 'latest'
|
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
return new Promise((resolve, reject) => {
|
if (channel === 'latest') {
|
||||||
const request = httpRequest(
|
return await getText(
|
||||||
new URL(
|
new URL(
|
||||||
`https://storage.googleapis.com/chromium-browser-snapshots/${folder(
|
`https://storage.googleapis.com/chromium-browser-snapshots/${folder(
|
||||||
platform
|
platform
|
||||||
)}/LAST_CHANGE`
|
)}/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
|
* @public
|
||||||
*/
|
*/
|
||||||
export enum BrowserTag {
|
export enum BrowserTag {
|
||||||
|
CANARY = 'canary',
|
||||||
|
BETA = 'beta',
|
||||||
|
DEV = 'dev',
|
||||||
|
STABLE = 'stable',
|
||||||
LATEST = 'latest',
|
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"],
|
"parameters": ["webDriverBiDi"],
|
||||||
"expectations": ["PASS"]
|
"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] *",
|
"testIdPattern": "[proxy.spec] *",
|
||||||
"platforms": ["darwin", "linux", "win32"],
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
@ -1769,30 +1793,6 @@
|
|||||||
"parameters": ["cdp", "firefox"],
|
"parameters": ["cdp", "firefox"],
|
||||||
"expectations": ["FAIL"]
|
"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",
|
"testIdPattern": "[page.spec] Page Page.setGeolocation should work",
|
||||||
"platforms": ["darwin", "linux", "win32"],
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
|
Loading…
Reference in New Issue
Block a user