Skip to content

Commit

Permalink
feat: support stable/dev/beta/canary keywords for chrome and chromium (
Browse files Browse the repository at this point in the history
  • Loading branch information
OrKoN committed May 8, 2023
1 parent baf2a86 commit 90ed263
Show file tree
Hide file tree
Showing 8 changed files with 163 additions and 106 deletions.
2 changes: 1 addition & 1 deletion docs/browsers-api/index.md
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion packages/browsers/README.md
Expand Up @@ -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
Expand Down
56 changes: 54 additions & 2 deletions packages/browsers/src/browser-data/browser-data.ts
Expand Up @@ -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.
Expand Down
81 changes: 32 additions & 49 deletions packages/browsers/src/browser-data/chrome.ts
Expand Up @@ -16,7 +16,7 @@

import path from 'path';

import {httpRequest} from '../httpUtil.js';
import {getJSON} from '../httpUtil.js';

import {BrowserPlatform, ChromeReleaseChannel} from './types.js';

Expand All @@ -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,
Expand Down Expand Up @@ -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(
Expand Down
38 changes: 9 additions & 29 deletions packages/browsers/src/browser-data/chromium.ts
Expand Up @@ -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';

Expand Down Expand Up @@ -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;
}
4 changes: 4 additions & 0 deletions packages/browsers/src/browser-data/types.ts
Expand Up @@ -53,6 +53,10 @@ export const downloadUrls = {
* @public
*/
export enum BrowserTag {
CANARY = 'canary',
BETA = 'beta',
DEV = 'dev',
STABLE = 'stable',
LATEST = 'latest',
}

Expand Down
38 changes: 38 additions & 0 deletions packages/browsers/src/httpUtil.ts
Expand Up @@ -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);
});
});
}
48 changes: 24 additions & 24 deletions test/TestExpectations.json
Expand Up @@ -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"],
Expand Down Expand Up @@ -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"],
Expand Down

0 comments on commit 90ed263

Please sign in to comment.