fetch chrome using which
This commit is contained in:
parent
2cbaf0450c
commit
59605be103
6 changed files with 77 additions and 35 deletions
4
.github/workflows/test.yml
vendored
4
.github/workflows/test.yml
vendored
|
|
@ -29,7 +29,9 @@ jobs:
|
|||
- name: Lint / Typings / Unit / Smoke Tests
|
||||
run: npm run test
|
||||
- name: Interop Tests
|
||||
run: npm run test:e2e:cjs
|
||||
run:
|
||||
npm i chromedriver@104
|
||||
npm run test:e2e:cjs
|
||||
e2e-windows:
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
|
|
|
|||
6
__mocks__/which.ts
Normal file
6
__mocks__/which.ts
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
import { vi } from 'vitest'
|
||||
|
||||
const which = vi.fn()
|
||||
// @ts-expect-error
|
||||
which.sync = vi.fn()
|
||||
export default which
|
||||
|
|
@ -45,7 +45,8 @@
|
|||
"puppeteer-core": "^17.0.0",
|
||||
"query-selector-shadow-dom": "^1.0.0",
|
||||
"ua-parser-js": "^1.0.1",
|
||||
"uuid": "^9.0.0"
|
||||
"uuid": "^9.0.0",
|
||||
"which": "^2.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^18.0.0",
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { launch as launchChromeBrowser } from 'chrome-launcher'
|
||||
import { launch as launchChromeBrowser, Options } from 'chrome-launcher'
|
||||
import puppeteer, { PuppeteerLaunchOptions } from 'puppeteer-core'
|
||||
import logger from '@wdio/logger'
|
||||
import type { Browser } from 'puppeteer-core/lib/cjs/puppeteer/common/Browser'
|
||||
|
|
@ -6,7 +6,7 @@ import type { Capabilities } from '@wdio/types'
|
|||
import { QueryHandler } from 'query-selector-shadow-dom/plugins/puppeteer/index.js'
|
||||
|
||||
import browserFinder from './finder/index.js'
|
||||
import { getPages } from './utils.js'
|
||||
import { getPages, launchChromeUsingWhich } from './utils.js'
|
||||
import {
|
||||
CHROME_NAMES,
|
||||
FIREFOX_NAMES,
|
||||
|
|
@ -106,7 +106,7 @@ async function launchChrome (capabilities: ExtendedCapabilities) {
|
|||
}
|
||||
|
||||
log.info(`Launch Google Chrome with flags: ${chromeFlags.join(' ')}`)
|
||||
const chrome = await launchChromeBrowser({
|
||||
const launchOptions: Options = {
|
||||
prefs: chromeOptions.prefs,
|
||||
chromePath: chromeOptions.binary,
|
||||
ignoreDefaultFlags: true,
|
||||
|
|
@ -114,7 +114,9 @@ async function launchChrome (capabilities: ExtendedCapabilities) {
|
|||
userDataDir,
|
||||
envVars: devtoolsOptions.env,
|
||||
...(devtoolsOptions.customPort ? { port: devtoolsOptions.customPort } : {})
|
||||
})
|
||||
}
|
||||
const chrome = await launchChromeBrowser(launchOptions).catch(
|
||||
(err: Error) => launchChromeUsingWhich(err, launchOptions))
|
||||
|
||||
log.info(`Connect Puppeteer with browser on port ${chrome.port}`)
|
||||
const browser = await puppeteer.connect({
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
import fs from 'node:fs'
|
||||
import { createRequire } from 'node:module'
|
||||
import { execFileSync } from 'node:child_process'
|
||||
|
||||
import which from 'which'
|
||||
import logger from '@wdio/logger'
|
||||
import { commandCallStructure, isValidParameter, getArgumentType, canAccess } from '@wdio/utils'
|
||||
import { WebDriverProtocol, CommandParameters, CommandPathVariables, ElementReference } from '@wdio/protocols'
|
||||
import { launch as launchChromeBrowser, Options } from 'chrome-launcher'
|
||||
import type { Logger } from '@wdio/logger/build/node'
|
||||
import type { ElementHandle } from 'puppeteer-core/lib/cjs/puppeteer/common/ElementHandle'
|
||||
import type { Browser } from 'puppeteer-core/lib/cjs/puppeteer/common/Browser'
|
||||
|
|
@ -302,12 +303,7 @@ export function findByWhich (executables: string[], priorities: Priorities[]) {
|
|||
const installations: string[] = []
|
||||
executables.forEach((executable) => {
|
||||
try {
|
||||
const browserPath = execFileSync(
|
||||
'which',
|
||||
[executable],
|
||||
{ stdio: 'pipe' }
|
||||
).toString().split(/\r?\n/)[0]
|
||||
|
||||
const browserPath = which.sync(executable)
|
||||
if (canAccess(browserPath)) {
|
||||
installations.push(browserPath)
|
||||
}
|
||||
|
|
@ -374,3 +370,29 @@ export async function patchDebug (scoppedLogger: Logger) {
|
|||
|
||||
export const sleep = (time = 0) => new Promise(
|
||||
(resolve) => setTimeout(resolve, time))
|
||||
|
||||
export const launchChromeUsingWhich = async (err: Error, launchOptions: Options, ) => {
|
||||
/**
|
||||
* we only handle the error if
|
||||
*/
|
||||
if (
|
||||
/**
|
||||
* the installation could not be found
|
||||
*/
|
||||
!err.message.includes('No Chrome installations found.') ||
|
||||
/**
|
||||
* the user specified a binary path that could not be found
|
||||
*/
|
||||
typeof launchOptions.chromePath === 'string'
|
||||
) {
|
||||
throw err
|
||||
}
|
||||
|
||||
/**
|
||||
* try to use node-which to resolve a Chrome path
|
||||
*/
|
||||
const chromePath = await which('chrome')
|
||||
.catch(() => which('chromium')
|
||||
.catch(() => which('google-chrome')))
|
||||
return launchChromeBrowser({ ...launchOptions, chromePath })
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,17 +1,20 @@
|
|||
import { describe, it, expect, afterEach, vi, test } from 'vitest'
|
||||
|
||||
import path from 'node:path'
|
||||
import childProcess from 'node:child_process'
|
||||
// @ts-ignore no types needed
|
||||
import debug from 'debug'
|
||||
import which from 'which'
|
||||
import { launch } from 'chrome-launcher'
|
||||
import { canAccess } from '@wdio/utils'
|
||||
|
||||
import {
|
||||
validate, getPrototype, findElement, findElements, getStaleElementError,
|
||||
sanitizeError, transformExecuteArgs, transformExecuteResult, getPages,
|
||||
uniq, findByWhich, patchDebug, sleep
|
||||
uniq, findByWhich, patchDebug, sleep, launchChromeUsingWhich
|
||||
} from '../src/utils.js'
|
||||
|
||||
vi.mock('which')
|
||||
vi.mock('chrome-launcher')
|
||||
vi.mock('@wdio/logger', async () => {
|
||||
const pathModule = await vi.importActual('node:path') as typeof path
|
||||
return import(pathModule.join(process.cwd(), '__mocks__', '@wdio/logger'))
|
||||
|
|
@ -85,24 +88,6 @@ vi.mock('fs', () => {
|
|||
}
|
||||
})
|
||||
|
||||
vi.mock('node:child_process', () => {
|
||||
let returnValue = false
|
||||
const execFileSync = vi.fn().mockImplementation(() => {
|
||||
if (!returnValue) {
|
||||
throw new Error('foo not found')
|
||||
}
|
||||
return returnValue
|
||||
})
|
||||
|
||||
return {
|
||||
execFileSync,
|
||||
default: {
|
||||
execFileSync,
|
||||
shouldReturn: (value: any) => (returnValue = value)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
vi.mock('debug', () => ({
|
||||
default: { log: vi.fn() }
|
||||
}))
|
||||
|
|
@ -400,8 +385,7 @@ test('findByWhich', () => {
|
|||
expect(findByWhich(['firefox'], [{ regex: /firefox/, weight: 51 }]))
|
||||
.toEqual([])
|
||||
|
||||
// @ts-expect-error mock feature
|
||||
vi.mocked(childProcess).shouldReturn('/path/to/other/firefox\n')
|
||||
vi.mocked(which.sync).mockReturnValue('/path/to/other/firefox')
|
||||
expect(findByWhich(['firefox'], [{ regex: /firefox/, weight: 51 }]))
|
||||
.toEqual(['/path/to/other/firefox'])
|
||||
|
||||
|
|
@ -430,3 +414,28 @@ test('sleep', async () => {
|
|||
await sleep(100)
|
||||
expect(Date.now() - start).toBeGreaterThanOrEqual(90)
|
||||
})
|
||||
|
||||
describe('launchChromeUsingWhich', () => {
|
||||
it('should throw if error is not related to chrome binary not found', async () => {
|
||||
await expect(() => launchChromeUsingWhich(new Error('ups'), {}))
|
||||
.rejects.toThrow('ups')
|
||||
})
|
||||
|
||||
it('should throw if user has specified path explicitly', async () => {
|
||||
await expect(() => launchChromeUsingWhich(
|
||||
new Error('No Chrome installations found.'),
|
||||
{ chromePath: '/foo/bar' }
|
||||
)).rejects.toThrow('No Chrome installations found.')
|
||||
})
|
||||
|
||||
it('should use which properly to find path', async () => {
|
||||
vi.mocked(which).mockImplementation(async (binary: string) => {
|
||||
if (binary === 'google-chrome') {
|
||||
return '/foo/bar/google-chrome'
|
||||
}
|
||||
throw new Error('not found')
|
||||
})
|
||||
await launchChromeUsingWhich(new Error('No Chrome installations found.'), {})
|
||||
expect(launch).toBeCalledWith({ chromePath: '/foo/bar/google-chrome' })
|
||||
})
|
||||
})
|
||||
|
|
|
|||
Loading…
Reference in a new issue