chore: update headless shell treatment (#33603)
This commit is contained in:
parent
9f59dbdc57
commit
31a2b7bbdc
31
.github/workflows/tests_secondary.yml
vendored
31
.github/workflows/tests_secondary.yml
vendored
|
|
@ -268,29 +268,8 @@ jobs:
|
||||||
- run: npx playwright install-deps
|
- run: npx playwright install-deps
|
||||||
- run: utils/build/build-playwright-driver.sh
|
- run: utils/build/build-playwright-driver.sh
|
||||||
|
|
||||||
test_linux_chromium_headless_shell:
|
test_channel_chromium:
|
||||||
name: Chromium Headless Shell
|
name: Test channel=chromium
|
||||||
environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
runs-on: [ubuntu-latest]
|
|
||||||
runs-on: ${{ matrix.runs-on }}
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- uses: ./.github/actions/run-test
|
|
||||||
with:
|
|
||||||
browsers-to-install: chromium chromium-headless-shell
|
|
||||||
command: npm run ctest
|
|
||||||
bot-name: "headless-shell-${{ matrix.runs-on }}"
|
|
||||||
flakiness-client-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_CLIENT_ID }}
|
|
||||||
flakiness-tenant-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_TENANT_ID }}
|
|
||||||
flakiness-subscription-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_SUBSCRIPTION_ID }}
|
|
||||||
env:
|
|
||||||
PWTEST_CHANNEL: chromium-headless-shell
|
|
||||||
|
|
||||||
test_chromium_next:
|
|
||||||
name: Test chromium-next channel
|
|
||||||
environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
|
environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
|
|
@ -301,11 +280,13 @@ jobs:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: ./.github/actions/run-test
|
- uses: ./.github/actions/run-test
|
||||||
with:
|
with:
|
||||||
|
# TODO: this should pass --no-shell.
|
||||||
|
# However, codegen tests do not inherit the channel and try to launch headless shell.
|
||||||
browsers-to-install: chromium
|
browsers-to-install: chromium
|
||||||
command: npm run ctest
|
command: npm run ctest
|
||||||
bot-name: "chromium-next-${{ matrix.runs-on }}"
|
bot-name: "channel-chromium-${{ matrix.runs-on }}"
|
||||||
flakiness-client-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_CLIENT_ID }}
|
flakiness-client-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_CLIENT_ID }}
|
||||||
flakiness-tenant-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_TENANT_ID }}
|
flakiness-tenant-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_TENANT_ID }}
|
||||||
flakiness-subscription-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_SUBSCRIPTION_ID }}
|
flakiness-subscription-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_SUBSCRIPTION_ID }}
|
||||||
env:
|
env:
|
||||||
PWTEST_CHANNEL: chromium-next
|
PWTEST_CHANNEL: chromium
|
||||||
|
|
|
||||||
|
|
@ -24,4 +24,4 @@ try {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (install)
|
if (install)
|
||||||
install(['chromium', 'ffmpeg']);
|
install(['chromium', 'chromium-headless-shell', 'ffmpeg']);
|
||||||
|
|
|
||||||
|
|
@ -24,4 +24,4 @@ try {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (install)
|
if (install)
|
||||||
install(['chromium', 'ffmpeg']);
|
install(['chromium', 'chromium-headless-shell', 'ffmpeg']);
|
||||||
|
|
|
||||||
|
|
@ -96,16 +96,42 @@ function suggestedBrowsersToInstall() {
|
||||||
return registry.executables().filter(e => e.installType !== 'none' && e.type !== 'tool').map(e => e.name).join(', ');
|
return registry.executables().filter(e => e.installType !== 'none' && e.type !== 'tool').map(e => e.name).join(', ');
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkBrowsersToInstall(args: string[]): Executable[] {
|
function defaultBrowsersToInstall(options: { noShell?: boolean, onlyShell?: boolean }): Executable[] {
|
||||||
|
let executables = registry.defaultExecutables();
|
||||||
|
if (options.noShell)
|
||||||
|
executables = executables.filter(e => e.name !== 'chromium-headless-shell');
|
||||||
|
if (options.onlyShell)
|
||||||
|
executables = executables.filter(e => e.name !== 'chromium');
|
||||||
|
return executables;
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkBrowsersToInstall(args: string[], options: { noShell?: boolean, onlyShell?: boolean }): Executable[] {
|
||||||
|
if (options.noShell && options.onlyShell)
|
||||||
|
throw new Error(`Only one of --no-shell and --only-shell can be specified`);
|
||||||
|
|
||||||
const faultyArguments: string[] = [];
|
const faultyArguments: string[] = [];
|
||||||
const executables: Executable[] = [];
|
const executables: Executable[] = [];
|
||||||
for (const arg of args) {
|
const handleArgument = (arg: string) => {
|
||||||
const executable = registry.findExecutable(arg);
|
const executable = registry.findExecutable(arg);
|
||||||
if (!executable || executable.installType === 'none')
|
if (!executable || executable.installType === 'none')
|
||||||
faultyArguments.push(arg);
|
faultyArguments.push(arg);
|
||||||
else
|
else
|
||||||
executables.push(executable);
|
executables.push(executable);
|
||||||
|
if (executable?.browserName === 'chromium')
|
||||||
|
executables.push(registry.findExecutable('ffmpeg')!);
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const arg of args) {
|
||||||
|
if (arg === 'chromium') {
|
||||||
|
if (!options.onlyShell)
|
||||||
|
handleArgument('chromium');
|
||||||
|
if (!options.noShell)
|
||||||
|
handleArgument('chromium-headless-shell');
|
||||||
|
} else {
|
||||||
|
handleArgument(arg);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (faultyArguments.length)
|
if (faultyArguments.length)
|
||||||
throw new Error(`Invalid installation targets: ${faultyArguments.map(name => `'${name}'`).join(', ')}. Expecting one of: ${suggestedBrowsersToInstall()}`);
|
throw new Error(`Invalid installation targets: ${faultyArguments.map(name => `'${name}'`).join(', ')}. Expecting one of: ${suggestedBrowsersToInstall()}`);
|
||||||
return executables;
|
return executables;
|
||||||
|
|
@ -118,7 +144,12 @@ program
|
||||||
.option('--with-deps', 'install system dependencies for browsers')
|
.option('--with-deps', 'install system dependencies for browsers')
|
||||||
.option('--dry-run', 'do not execute installation, only print information')
|
.option('--dry-run', 'do not execute installation, only print information')
|
||||||
.option('--force', 'force reinstall of stable browser channels')
|
.option('--force', 'force reinstall of stable browser channels')
|
||||||
.action(async function(args: string[], options: { withDeps?: boolean, force?: boolean, dryRun?: boolean }) {
|
.option('--only-shell', 'only install headless shell when installing chromium')
|
||||||
|
.option('--no-shell', 'do not install chromium headless shell')
|
||||||
|
.action(async function(args: string[], options: { withDeps?: boolean, force?: boolean, dryRun?: boolean, shell?: boolean, noShell?: boolean, onlyShell?: boolean }) {
|
||||||
|
// For '--no-shell' option, commander sets `shell: false` instead.
|
||||||
|
if (options.shell === false)
|
||||||
|
options.noShell = true;
|
||||||
if (isLikelyNpxGlobal()) {
|
if (isLikelyNpxGlobal()) {
|
||||||
console.error(wrapInASCIIBox([
|
console.error(wrapInASCIIBox([
|
||||||
`WARNING: It looks like you are running 'npx playwright install' without first`,
|
`WARNING: It looks like you are running 'npx playwright install' without first`,
|
||||||
|
|
@ -141,7 +172,7 @@ program
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const hasNoArguments = !args.length;
|
const hasNoArguments = !args.length;
|
||||||
const executables = hasNoArguments ? registry.defaultExecutables() : checkBrowsersToInstall(args);
|
const executables = hasNoArguments ? defaultBrowsersToInstall(options) : checkBrowsersToInstall(args, options);
|
||||||
if (options.withDeps)
|
if (options.withDeps)
|
||||||
await registry.installDeps(executables, !!options.dryRun);
|
await registry.installDeps(executables, !!options.dryRun);
|
||||||
if (options.dryRun) {
|
if (options.dryRun) {
|
||||||
|
|
@ -199,9 +230,9 @@ program
|
||||||
.action(async function(args: string[], options: { dryRun?: boolean }) {
|
.action(async function(args: string[], options: { dryRun?: boolean }) {
|
||||||
try {
|
try {
|
||||||
if (!args.length)
|
if (!args.length)
|
||||||
await registry.installDeps(registry.defaultExecutables(), !!options.dryRun);
|
await registry.installDeps(defaultBrowsersToInstall({}), !!options.dryRun);
|
||||||
else
|
else
|
||||||
await registry.installDeps(checkBrowsersToInstall(args), !!options.dryRun);
|
await registry.installDeps(checkBrowsersToInstall(args, {}), !!options.dryRun);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(`Failed to install browser dependencies\n${e}`);
|
console.log(`Failed to install browser dependencies\n${e}`);
|
||||||
gracefullyProcessExitDoNotHang(1);
|
gracefullyProcessExitDoNotHang(1);
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,6 @@ export {
|
||||||
registry,
|
registry,
|
||||||
registryDirectory,
|
registryDirectory,
|
||||||
Registry,
|
Registry,
|
||||||
installDefaultBrowsersForNpmInstall,
|
|
||||||
installBrowsersForNpmInstall,
|
installBrowsersForNpmInstall,
|
||||||
writeDockerVersion } from './registry';
|
writeDockerVersion } from './registry';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ const EXECUTABLE_PATHS = {
|
||||||
};
|
};
|
||||||
|
|
||||||
type DownloadPaths = Record<HostPlatform, string | undefined>;
|
type DownloadPaths = Record<HostPlatform, string | undefined>;
|
||||||
const DOWNLOAD_PATHS: Record<BrowserName | InternalTool | 'chromium-headless-shell', DownloadPaths> = {
|
const DOWNLOAD_PATHS: Record<BrowserName | InternalTool, DownloadPaths> = {
|
||||||
'chromium': {
|
'chromium': {
|
||||||
'<unknown>': undefined,
|
'<unknown>': undefined,
|
||||||
'ubuntu18.04-x64': undefined,
|
'ubuntu18.04-x64': undefined,
|
||||||
|
|
@ -403,9 +403,9 @@ function readDescriptors(browsersJSON: BrowsersJSON): BrowsersJSONDescriptor[] {
|
||||||
}
|
}
|
||||||
|
|
||||||
export type BrowserName = 'chromium' | 'firefox' | 'webkit' | 'bidi';
|
export type BrowserName = 'chromium' | 'firefox' | 'webkit' | 'bidi';
|
||||||
type InternalTool = 'ffmpeg' | 'firefox-beta' | 'chromium-tip-of-tree' | 'android';
|
type InternalTool = 'ffmpeg' | 'firefox-beta' | 'chromium-tip-of-tree' | 'chromium-headless-shell' | 'android';
|
||||||
type BidiChannel = 'bidi-firefox-stable' | 'bidi-firefox-beta' | 'bidi-firefox-nightly' | 'bidi-chrome-canary' | 'bidi-chrome-stable' | 'bidi-chromium';
|
type BidiChannel = 'bidi-firefox-stable' | 'bidi-firefox-beta' | 'bidi-firefox-nightly' | 'bidi-chrome-canary' | 'bidi-chrome-stable' | 'bidi-chromium';
|
||||||
type ChromiumChannel = 'chrome' | 'chrome-beta' | 'chrome-dev' | 'chrome-canary' | 'chromium-headless-shell' | 'chromium-next' | 'msedge' | 'msedge-beta' | 'msedge-dev' | 'msedge-canary';
|
type ChromiumChannel = 'chrome' | 'chrome-beta' | 'chrome-dev' | 'chrome-canary' | 'msedge' | 'msedge-beta' | 'msedge-dev' | 'msedge-canary';
|
||||||
const allDownloadable = ['android', 'chromium', 'firefox', 'webkit', 'ffmpeg', 'firefox-beta', 'chromium-tip-of-tree', 'chromium-headless-shell'];
|
const allDownloadable = ['android', 'chromium', 'firefox', 'webkit', 'ffmpeg', 'firefox-beta', 'chromium-tip-of-tree', 'chromium-headless-shell'];
|
||||||
|
|
||||||
export interface Executable {
|
export interface Executable {
|
||||||
|
|
@ -488,21 +488,6 @@ export class Registry {
|
||||||
_dependencyGroup: 'chromium',
|
_dependencyGroup: 'chromium',
|
||||||
_isHermeticInstallation: true,
|
_isHermeticInstallation: true,
|
||||||
});
|
});
|
||||||
this._executables.push({
|
|
||||||
type: 'channel',
|
|
||||||
name: 'chromium-next',
|
|
||||||
browserName: 'chromium',
|
|
||||||
directory: chromium.dir,
|
|
||||||
executablePath: () => chromiumExecutable,
|
|
||||||
executablePathOrDie: (sdkLanguage: string) => executablePathOrDie('chromium-next', chromiumExecutable, chromium.installByDefault, sdkLanguage),
|
|
||||||
installType: 'download-on-demand',
|
|
||||||
_validateHostRequirements: (sdkLanguage: string) => this._validateHostRequirements(sdkLanguage, chromium.dir, ['chrome-linux'], [], ['chrome-win']),
|
|
||||||
downloadURLs: this._downloadURLs(chromium),
|
|
||||||
browserVersion: chromium.browserVersion,
|
|
||||||
_install: () => this._downloadExecutable(chromium, chromiumExecutable),
|
|
||||||
_dependencyGroup: 'chromium',
|
|
||||||
_isHermeticInstallation: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
const chromiumHeadlessShell = descriptors.find(d => d.name === 'chromium-headless-shell')!;
|
const chromiumHeadlessShell = descriptors.find(d => d.name === 'chromium-headless-shell')!;
|
||||||
const chromiumHeadlessShellExecutable = findExecutablePath(chromiumHeadlessShell.dir, 'chromium-headless-shell');
|
const chromiumHeadlessShellExecutable = findExecutablePath(chromiumHeadlessShell.dir, 'chromium-headless-shell');
|
||||||
|
|
@ -512,7 +497,7 @@ export class Registry {
|
||||||
browserName: 'chromium',
|
browserName: 'chromium',
|
||||||
directory: chromiumHeadlessShell.dir,
|
directory: chromiumHeadlessShell.dir,
|
||||||
executablePath: () => chromiumHeadlessShellExecutable,
|
executablePath: () => chromiumHeadlessShellExecutable,
|
||||||
executablePathOrDie: (sdkLanguage: string) => executablePathOrDie('chromium-headless-shell', chromiumHeadlessShellExecutable, false, sdkLanguage),
|
executablePathOrDie: (sdkLanguage: string) => executablePathOrDie('chromium', chromiumHeadlessShellExecutable, chromiumHeadlessShell.installByDefault, sdkLanguage),
|
||||||
installType: chromiumHeadlessShell.installByDefault ? 'download-by-default' : 'download-on-demand',
|
installType: chromiumHeadlessShell.installByDefault ? 'download-by-default' : 'download-on-demand',
|
||||||
_validateHostRequirements: (sdkLanguage: string) => this._validateHostRequirements(sdkLanguage, chromiumHeadlessShell.dir, ['chrome-linux'], [], ['chrome-win']),
|
_validateHostRequirements: (sdkLanguage: string) => this._validateHostRequirements(sdkLanguage, chromiumHeadlessShell.dir, ['chrome-linux'], [], ['chrome-win']),
|
||||||
downloadURLs: this._downloadURLs(chromiumHeadlessShell),
|
downloadURLs: this._downloadURLs(chromiumHeadlessShell),
|
||||||
|
|
@ -894,16 +879,8 @@ export class Registry {
|
||||||
return this._executables.filter(e => e.installType === 'download-by-default');
|
return this._executables.filter(e => e.installType === 'download-by-default');
|
||||||
}
|
}
|
||||||
|
|
||||||
private _addRequirementsAndDedupe(executables: Executable[]): ExecutableImpl[] {
|
private _dedupe(executables: Executable[]): ExecutableImpl[] {
|
||||||
const set = new Set<ExecutableImpl>();
|
return Array.from(new Set(executables as ExecutableImpl[]));
|
||||||
for (const executable of executables as ExecutableImpl[]) {
|
|
||||||
set.add(executable);
|
|
||||||
if (executable.browserName === 'chromium')
|
|
||||||
set.add(this.findExecutable('ffmpeg')!);
|
|
||||||
if (executable.name === 'chromium')
|
|
||||||
set.add(this.findExecutable('chromium-headless-shell')!);
|
|
||||||
}
|
|
||||||
return Array.from(set);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _validateHostRequirements(sdkLanguage: string, browserDirectory: string, linuxLddDirectories: string[], dlOpenLibraries: string[], windowsExeAndDllDirectories: string[]) {
|
private async _validateHostRequirements(sdkLanguage: string, browserDirectory: string, linuxLddDirectories: string[], dlOpenLibraries: string[], windowsExeAndDllDirectories: string[]) {
|
||||||
|
|
@ -914,7 +891,7 @@ export class Registry {
|
||||||
}
|
}
|
||||||
|
|
||||||
async installDeps(executablesToInstallDeps: Executable[], dryRun: boolean) {
|
async installDeps(executablesToInstallDeps: Executable[], dryRun: boolean) {
|
||||||
const executables = this._addRequirementsAndDedupe(executablesToInstallDeps);
|
const executables = this._dedupe(executablesToInstallDeps);
|
||||||
const targets = new Set<DependencyGroup>();
|
const targets = new Set<DependencyGroup>();
|
||||||
for (const executable of executables) {
|
for (const executable of executables) {
|
||||||
if (executable._dependencyGroup)
|
if (executable._dependencyGroup)
|
||||||
|
|
@ -928,7 +905,7 @@ export class Registry {
|
||||||
}
|
}
|
||||||
|
|
||||||
async install(executablesToInstall: Executable[], forceReinstall: boolean) {
|
async install(executablesToInstall: Executable[], forceReinstall: boolean) {
|
||||||
const executables = this._addRequirementsAndDedupe(executablesToInstall);
|
const executables = this._dedupe(executablesToInstall);
|
||||||
await fs.promises.mkdir(registryDirectory, { recursive: true });
|
await fs.promises.mkdir(registryDirectory, { recursive: true });
|
||||||
const lockfilePath = path.join(registryDirectory, '__dirlock');
|
const lockfilePath = path.join(registryDirectory, '__dirlock');
|
||||||
const linksDir = path.join(registryDirectory, '.links');
|
const linksDir = path.join(registryDirectory, '.links');
|
||||||
|
|
@ -1224,11 +1201,6 @@ export function buildPlaywrightCLICommand(sdkLanguage: string, parameters: strin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function installDefaultBrowsersForNpmInstall() {
|
|
||||||
const defaultBrowserNames = registry.defaultExecutables().map(e => e.name);
|
|
||||||
return installBrowsersForNpmInstall(defaultBrowserNames);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function installBrowsersForNpmInstall(browsers: string[]) {
|
export async function installBrowsersForNpmInstall(browsers: string[]) {
|
||||||
// PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD should have a value of 0 or 1
|
// PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD should have a value of 0 or 1
|
||||||
if (getAsBooleanFromENV('PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD')) {
|
if (getAsBooleanFromENV('PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD')) {
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ export type BrowserTestWorkerFixtures = PageWorkerFixtures & {
|
||||||
browserType: BrowserType;
|
browserType: BrowserType;
|
||||||
isAndroid: boolean;
|
isAndroid: boolean;
|
||||||
isElectron: boolean;
|
isElectron: boolean;
|
||||||
|
isHeadlessShell: boolean;
|
||||||
nodeVersion: { major: number, minor: number, patch: number };
|
nodeVersion: { major: number, minor: number, patch: number };
|
||||||
bidiTestSkipPredicate: (info: TestInfo) => boolean;
|
bidiTestSkipPredicate: (info: TestInfo) => boolean;
|
||||||
};
|
};
|
||||||
|
|
@ -97,6 +98,10 @@ const test = baseTest.extend<BrowserTestTestFixtures, BrowserTestWorkerFixtures>
|
||||||
electronMajorVersion: [0, { scope: 'worker' }],
|
electronMajorVersion: [0, { scope: 'worker' }],
|
||||||
isWebView2: [false, { scope: 'worker' }],
|
isWebView2: [false, { scope: 'worker' }],
|
||||||
|
|
||||||
|
isHeadlessShell: [async ({ browserName, channel, headless }, use) => {
|
||||||
|
await use(browserName === 'chromium' && (channel === 'chromium-headless-shell' || (!channel && headless)));
|
||||||
|
}, { scope: 'worker' }],
|
||||||
|
|
||||||
contextFactory: async ({ _contextFactory }: any, run) => {
|
contextFactory: async ({ _contextFactory }: any, run) => {
|
||||||
await run(_contextFactory);
|
await run(_contextFactory);
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -76,15 +76,24 @@ test(`playwright should work`, async ({ exec, installedSoftwareOnDisk }) => {
|
||||||
await exec('node esm-playwright.mjs');
|
await exec('node esm-playwright.mjs');
|
||||||
});
|
});
|
||||||
|
|
||||||
test(`playwright should work with chromium-next`, async ({ exec, installedSoftwareOnDisk }) => {
|
test(`playwright should work with chromium --no-shell`, async ({ exec, installedSoftwareOnDisk }) => {
|
||||||
const result1 = await exec('npm i --foreground-scripts playwright');
|
const result1 = await exec('npm i --foreground-scripts playwright');
|
||||||
expect(result1).toHaveLoggedSoftwareDownload([]);
|
expect(result1).toHaveLoggedSoftwareDownload([]);
|
||||||
expect(await installedSoftwareOnDisk()).toEqual([]);
|
expect(await installedSoftwareOnDisk()).toEqual([]);
|
||||||
const result2 = await exec('npx playwright install chromium-next');
|
const result2 = await exec('npx playwright install chromium --no-shell');
|
||||||
expect(result2).toHaveLoggedSoftwareDownload(['chromium', 'ffmpeg']);
|
expect(result2).toHaveLoggedSoftwareDownload(['chromium', 'ffmpeg']);
|
||||||
expect(await installedSoftwareOnDisk()).toEqual(['chromium', 'ffmpeg']);
|
expect(await installedSoftwareOnDisk()).toEqual(['chromium', 'ffmpeg']);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test(`playwright should work with chromium --only-shell`, async ({ exec, installedSoftwareOnDisk }) => {
|
||||||
|
const result1 = await exec('npm i --foreground-scripts playwright');
|
||||||
|
expect(result1).toHaveLoggedSoftwareDownload([]);
|
||||||
|
expect(await installedSoftwareOnDisk()).toEqual([]);
|
||||||
|
const result2 = await exec('npx playwright install --only-shell');
|
||||||
|
expect(result2).toHaveLoggedSoftwareDownload(['chromium-headless-shell', 'ffmpeg', 'firefox', 'webkit']);
|
||||||
|
expect(await installedSoftwareOnDisk()).toEqual(['chromium-headless-shell', 'ffmpeg', 'firefox', 'webkit']);
|
||||||
|
});
|
||||||
|
|
||||||
test('@playwright/test should work', async ({ exec, installedSoftwareOnDisk }) => {
|
test('@playwright/test should work', async ({ exec, installedSoftwareOnDisk }) => {
|
||||||
const result1 = await exec('npm i --foreground-scripts @playwright/test');
|
const result1 = await exec('npm i --foreground-scripts @playwright/test');
|
||||||
expect(result1).toHaveLoggedSoftwareDownload([]);
|
expect(result1).toHaveLoggedSoftwareDownload([]);
|
||||||
|
|
|
||||||
|
|
@ -18,8 +18,7 @@
|
||||||
import { browserTest as base, expect } from '../config/browserTest';
|
import { browserTest as base, expect } from '../config/browserTest';
|
||||||
|
|
||||||
const it = base.extend<{ failsOn401: boolean }>({
|
const it = base.extend<{ failsOn401: boolean }>({
|
||||||
failsOn401: async ({ browserName, headless, channel }, use) => {
|
failsOn401: async ({ browserName, isHeadlessShell }, use) => {
|
||||||
const isHeadlessShell = channel === 'chromium-headless-shell' || (!channel && headless);
|
|
||||||
await use(browserName === 'chromium' && !isHeadlessShell);
|
await use(browserName === 'chromium' && !isHeadlessShell);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -52,8 +52,7 @@ it('should open devtools when "devtools: true" option is given', async ({ browse
|
||||||
await browser.close();
|
await browser.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return background pages', async ({ browserType, createUserDataDir, asset, headless, channel }) => {
|
it('should return background pages', async ({ browserType, createUserDataDir, asset, isHeadlessShell }) => {
|
||||||
const isHeadlessShell = channel === 'chromium-headless-shell' || (!channel && headless);
|
|
||||||
it.skip(isHeadlessShell, 'Headless Shell has no support for extensions');
|
it.skip(isHeadlessShell, 'Headless Shell has no support for extensions');
|
||||||
|
|
||||||
const userDataDir = await createUserDataDir();
|
const userDataDir = await createUserDataDir();
|
||||||
|
|
@ -78,8 +77,7 @@ it('should return background pages', async ({ browserType, createUserDataDir, as
|
||||||
expect(context.backgroundPages().length).toBe(0);
|
expect(context.backgroundPages().length).toBe(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return background pages when recording video', async ({ browserType, createUserDataDir, asset, headless, channel }, testInfo) => {
|
it('should return background pages when recording video', async ({ browserType, createUserDataDir, asset, isHeadlessShell }, testInfo) => {
|
||||||
const isHeadlessShell = channel === 'chromium-headless-shell' || (!channel && headless);
|
|
||||||
it.skip(isHeadlessShell, 'Headless Shell has no support for extensions');
|
it.skip(isHeadlessShell, 'Headless Shell has no support for extensions');
|
||||||
|
|
||||||
const userDataDir = await createUserDataDir();
|
const userDataDir = await createUserDataDir();
|
||||||
|
|
@ -105,8 +103,7 @@ it('should return background pages when recording video', async ({ browserType,
|
||||||
await context.close();
|
await context.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should support request/response events when using backgroundPage()', async ({ browserType, createUserDataDir, asset, server, headless, channel }) => {
|
it('should support request/response events when using backgroundPage()', async ({ browserType, createUserDataDir, asset, server, isHeadlessShell }) => {
|
||||||
const isHeadlessShell = channel === 'chromium-headless-shell' || (!channel && headless);
|
|
||||||
it.skip(isHeadlessShell, 'Headless Shell has no support for extensions');
|
it.skip(isHeadlessShell, 'Headless Shell has no support for extensions');
|
||||||
|
|
||||||
server.setRoute('/empty.html', (req, res) => {
|
server.setRoute('/empty.html', (req, res) => {
|
||||||
|
|
@ -157,8 +154,7 @@ it('should support request/response events when using backgroundPage()', async (
|
||||||
|
|
||||||
it('should report console messages from content script', {
|
it('should report console messages from content script', {
|
||||||
annotation: { type: 'issue', description: 'https://github.com/microsoft/playwright/issues/32762' }
|
annotation: { type: 'issue', description: 'https://github.com/microsoft/playwright/issues/32762' }
|
||||||
}, async ({ browserType, createUserDataDir, asset, server, headless, channel }) => {
|
}, async ({ browserType, createUserDataDir, asset, server, isHeadlessShell }) => {
|
||||||
const isHeadlessShell = channel === 'chromium-headless-shell' || (!channel && headless);
|
|
||||||
it.skip(isHeadlessShell, 'Headless Shell has no support for extensions');
|
it.skip(isHeadlessShell, 'Headless Shell has no support for extensions');
|
||||||
|
|
||||||
const userDataDir = await createUserDataDir();
|
const userDataDir = await createUserDataDir();
|
||||||
|
|
|
||||||
|
|
@ -636,8 +636,7 @@ it('should be able to download a inline PDF file via response interception', asy
|
||||||
await page.close();
|
await page.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be able to download a inline PDF file via navigation', async ({ browser, server, asset, browserName, channel, headless }) => {
|
it('should be able to download a inline PDF file via navigation', async ({ browser, server, asset, browserName, isHeadlessShell }) => {
|
||||||
const isHeadlessShell = channel === 'chromium-headless-shell' || (!channel && headless);
|
|
||||||
it.skip(browserName === 'chromium' && !isHeadlessShell, 'We expect PDF Viewer to open up in headed Chromium');
|
it.skip(browserName === 'chromium' && !isHeadlessShell, 'We expect PDF Viewer to open up in headed Chromium');
|
||||||
|
|
||||||
const page = await browser.newPage();
|
const page = await browser.newPage();
|
||||||
|
|
|
||||||
|
|
@ -101,10 +101,9 @@ it('should change document.activeElement', async ({ page, server }) => {
|
||||||
expect(active).toEqual(['INPUT', 'TEXTAREA']);
|
expect(active).toEqual(['INPUT', 'TEXTAREA']);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not affect screenshots', async ({ page, server, browserName, headless, isWindows, channel }) => {
|
it('should not affect screenshots', async ({ page, server, browserName, headless, isWindows, isHeadlessShell }) => {
|
||||||
it.skip(browserName === 'webkit' && isWindows && !headless, 'WebKit/Windows/headed has a larger minimal viewport. See https://github.com/microsoft/playwright/issues/22616');
|
it.skip(browserName === 'webkit' && isWindows && !headless, 'WebKit/Windows/headed has a larger minimal viewport. See https://github.com/microsoft/playwright/issues/22616');
|
||||||
it.skip(browserName === 'firefox' && !headless, 'Firefox headed produces a different image');
|
it.skip(browserName === 'firefox' && !headless, 'Firefox headed produces a different image');
|
||||||
const isHeadlessShell = channel === 'chromium-headless-shell' || (!channel && headless);
|
|
||||||
it.fixme(browserName === 'chromium' && !isHeadlessShell, 'https://github.com/microsoft/playwright/issues/33330');
|
it.fixme(browserName === 'chromium' && !isHeadlessShell, 'https://github.com/microsoft/playwright/issues/33330');
|
||||||
|
|
||||||
const page2 = await page.context().newPage();
|
const page2 = await page.context().newPage();
|
||||||
|
|
|
||||||
|
|
@ -145,7 +145,7 @@ it.describe('permissions', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should support clipboard read', async ({ page, context, server, browserName, isWindows, isLinux, headless, channel }) => {
|
it('should support clipboard read', async ({ page, context, server, browserName, isWindows, isLinux, headless, isHeadlessShell }) => {
|
||||||
it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/27475' });
|
it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/27475' });
|
||||||
it.fail(browserName === 'firefox', 'No such permissions (requires flag) in Firefox');
|
it.fail(browserName === 'firefox', 'No such permissions (requires flag) in Firefox');
|
||||||
it.fixme(browserName === 'webkit' && isWindows, 'WebPasteboardProxy::allPasteboardItemInfo not implemented for Windows.');
|
it.fixme(browserName === 'webkit' && isWindows, 'WebPasteboardProxy::allPasteboardItemInfo not implemented for Windows.');
|
||||||
|
|
@ -156,8 +156,7 @@ it('should support clipboard read', async ({ page, context, server, browserName,
|
||||||
if (browserName !== 'webkit')
|
if (browserName !== 'webkit')
|
||||||
expect(await getPermission(page, 'clipboard-read')).toBe('prompt');
|
expect(await getPermission(page, 'clipboard-read')).toBe('prompt');
|
||||||
|
|
||||||
const isHeadlessShell = channel === 'chromium-headless-shell' || (!channel && headless);
|
if (isHeadlessShell) {
|
||||||
if (browserName === 'chromium' && isHeadlessShell) {
|
|
||||||
// Chromium (but not headless-shell) shows a dialog and does not resolve the promise.
|
// Chromium (but not headless-shell) shows a dialog and does not resolve the promise.
|
||||||
const error = await page.evaluate(() => navigator.clipboard.readText()).catch(e => e);
|
const error = await page.evaluate(() => navigator.clipboard.readText()).catch(e => e);
|
||||||
expect(error.toString()).toContain('denied');
|
expect(error.toString()).toContain('denied');
|
||||||
|
|
|
||||||
|
|
@ -22,8 +22,7 @@ import { verifyViewport } from '../config/utils';
|
||||||
browserTest.describe('page screenshot', () => {
|
browserTest.describe('page screenshot', () => {
|
||||||
browserTest.skip(({ browserName, headless }) => browserName === 'firefox' && !headless, 'Firefox headed produces a different image.');
|
browserTest.skip(({ browserName, headless }) => browserName === 'firefox' && !headless, 'Firefox headed produces a different image.');
|
||||||
|
|
||||||
browserTest('should run in parallel in multiple pages', async ({ server, contextFactory, browserName, headless, channel }) => {
|
browserTest('should run in parallel in multiple pages', async ({ server, contextFactory, browserName, isHeadlessShell }) => {
|
||||||
const isHeadlessShell = channel === 'chromium-headless-shell' || (!channel && headless);
|
|
||||||
browserTest.fixme(browserName === 'chromium' && !isHeadlessShell, 'https://github.com/microsoft/playwright/issues/33330');
|
browserTest.fixme(browserName === 'chromium' && !isHeadlessShell, 'https://github.com/microsoft/playwright/issues/33330');
|
||||||
|
|
||||||
const context = await contextFactory();
|
const context = await contextFactory();
|
||||||
|
|
|
||||||
|
|
@ -429,8 +429,7 @@ for (const params of [
|
||||||
height: 768,
|
height: 768,
|
||||||
}
|
}
|
||||||
]) {
|
]) {
|
||||||
browserTest(`should produce screencast frames ${params.id}`, async ({ video, contextFactory, browserName, platform, headless, channel }, testInfo) => {
|
browserTest(`should produce screencast frames ${params.id}`, async ({ video, contextFactory, browserName, platform, headless, isHeadlessShell }, testInfo) => {
|
||||||
const isHeadlessShell = channel === 'chromium-headless-shell' || (!channel && headless);
|
|
||||||
browserTest.skip(browserName === 'chromium' && video === 'on', 'Same screencast resolution conflicts');
|
browserTest.skip(browserName === 'chromium' && video === 'on', 'Same screencast resolution conflicts');
|
||||||
browserTest.fixme(browserName === 'chromium' && !isHeadlessShell, 'Chromium (but not headless-shell) screencast has a min width issue');
|
browserTest.fixme(browserName === 'chromium' && !isHeadlessShell, 'Chromium (but not headless-shell) screencast has a min width issue');
|
||||||
browserTest.fixme(params.id === 'fit' && browserName === 'chromium' && platform === 'darwin', 'High DPI maxes image at 600x600');
|
browserTest.fixme(params.id === 'fit' && browserName === 'chromium' && platform === 'darwin', 'High DPI maxes image at 600x600');
|
||||||
|
|
|
||||||
|
|
@ -473,9 +473,8 @@ it.describe('screencast', () => {
|
||||||
expect(videoFiles.length).toBe(2);
|
expect(videoFiles.length).toBe(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should scale frames down to the requested size ', async ({ browser, browserName, server, headless, channel }, testInfo) => {
|
it('should scale frames down to the requested size ', async ({ browser, browserName, server, headless, isHeadlessShell }, testInfo) => {
|
||||||
it.fixme(!headless, 'Fails on headed');
|
it.fixme(!headless, 'Fails on headed');
|
||||||
const isHeadlessShell = channel === 'chromium-headless-shell' || (!channel && headless);
|
|
||||||
it.fixme(browserName === 'chromium' && !isHeadlessShell, 'Chromium (but not headless shell) has a min width issue');
|
it.fixme(browserName === 'chromium' && !isHeadlessShell, 'Chromium (but not headless shell) has a min width issue');
|
||||||
|
|
||||||
const context = await browser.newContext({
|
const context = await browser.newContext({
|
||||||
|
|
@ -723,9 +722,8 @@ it.describe('screencast', () => {
|
||||||
expect(files.length).toBe(1);
|
expect(files.length).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should capture full viewport', async ({ browserType, browserName, isWindows, headless, channel }, testInfo) => {
|
it('should capture full viewport', async ({ browserType, browserName, isWindows, headless, isHeadlessShell }, testInfo) => {
|
||||||
it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/22411' });
|
it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/22411' });
|
||||||
const isHeadlessShell = channel === 'chromium-headless-shell' || (!channel && headless);
|
|
||||||
it.fixme(browserName === 'chromium' && !isHeadlessShell, 'The square is not on the video');
|
it.fixme(browserName === 'chromium' && !isHeadlessShell, 'The square is not on the video');
|
||||||
it.fixme(browserName === 'firefox' && isWindows, 'https://github.com/microsoft/playwright/issues/14405');
|
it.fixme(browserName === 'firefox' && isWindows, 'https://github.com/microsoft/playwright/issues/14405');
|
||||||
const size = { width: 600, height: 400 };
|
const size = { width: 600, height: 400 };
|
||||||
|
|
@ -759,9 +757,8 @@ it.describe('screencast', () => {
|
||||||
expectAll(pixels, almostRed);
|
expectAll(pixels, almostRed);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should capture full viewport on hidpi', async ({ browserType, browserName, headless, isWindows, isLinux, channel }, testInfo) => {
|
it('should capture full viewport on hidpi', async ({ browserType, browserName, headless, isWindows, isLinux, isHeadlessShell }, testInfo) => {
|
||||||
it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/22411' });
|
it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/22411' });
|
||||||
const isHeadlessShell = channel === 'chromium-headless-shell' || (!channel && headless);
|
|
||||||
it.fixme(browserName === 'chromium' && !isHeadlessShell, 'The square is not on the video');
|
it.fixme(browserName === 'chromium' && !isHeadlessShell, 'The square is not on the video');
|
||||||
it.fixme(browserName === 'firefox' && isWindows, 'https://github.com/microsoft/playwright/issues/14405');
|
it.fixme(browserName === 'firefox' && isWindows, 'https://github.com/microsoft/playwright/issues/14405');
|
||||||
it.fixme(browserName === 'webkit' && isLinux && !headless, 'https://github.com/microsoft/playwright/issues/22617');
|
it.fixme(browserName === 'webkit' && isLinux && !headless, 'https://github.com/microsoft/playwright/issues/22617');
|
||||||
|
|
@ -797,10 +794,9 @@ it.describe('screencast', () => {
|
||||||
expectAll(pixels, almostRed);
|
expectAll(pixels, almostRed);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should work with video+trace', async ({ browser, trace, headless, browserName, channel }, testInfo) => {
|
it('should work with video+trace', async ({ browser, trace, headless, browserName, isHeadlessShell }, testInfo) => {
|
||||||
it.skip(trace === 'on');
|
it.skip(trace === 'on');
|
||||||
it.fixme(!headless, 'different trace screencast image size on all browsers');
|
it.fixme(!headless, 'different trace screencast image size on all browsers');
|
||||||
const isHeadlessShell = channel === 'chromium-headless-shell' || (!channel && headless);
|
|
||||||
it.fixme(browserName === 'chromium' && !isHeadlessShell, 'different trace screencast image size');
|
it.fixme(browserName === 'chromium' && !isHeadlessShell, 'different trace screencast image size');
|
||||||
|
|
||||||
const size = { width: 500, height: 400 };
|
const size = { width: 500, height: 400 };
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue