Skip to content

Commit

Permalink
(@wdio/types): allow to extend capability interface (#11367)
Browse files Browse the repository at this point in the history
* (fix): allow to extend capability interface

* add docs

* fix types
  • Loading branch information
christian-bromann authored Oct 9, 2023
1 parent 6cd7033 commit 4277730
Show file tree
Hide file tree
Showing 89 changed files with 331 additions and 284 deletions.
3 changes: 1 addition & 2 deletions e2e/wdio/headless/secondTest.e2e.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { browser, $, expect } from '@wdio/globals'
import type { Capabilities } from '@wdio/types'

describe('main suite 1', () => {
it('foobar test', async () => {
const caps = browser.capabilities as Capabilities.Capabilities
const caps = browser.capabilities as WebdriverIO.Capabilities
const assertionValue = caps.browserName === 'msedge'
? 'headlessedg'
: caps.browserName!.toLowerCase()
Expand Down
3 changes: 1 addition & 2 deletions e2e/wdio/headless/test.e2e.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import os from 'node:os'
import type { Capabilities } from '../../../packages/wdio-types'

describe('main suite 1', () => {
it('foobar test', async () => {
const browserName = (browser.capabilities as Capabilities.Capabilities).browserName
const browserName = (browser.capabilities as WebdriverIO.Capabilities).browserName
await browser.url('http://guinea-pig.webdriver.io/')
await expect((await $('#useragent').getText()).toLowerCase()).toContain(browserName)
})
Expand Down
4 changes: 2 additions & 2 deletions e2e/wdio/wdio.local.conf.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import os from 'node:os'
import url from 'node:url'
import path from 'node:path'
import type { Capabilities, Options } from '@wdio/types'
import type { Options } from '@wdio/types'

const __dirname = path.dirname(url.fileURLToPath(import.meta.url))

Expand Down Expand Up @@ -62,7 +62,7 @@ export const config: Options.Testrunner = {
}

if (os.platform() === 'darwin') {
(config.capabilities as Capabilities.Capabilities[]).push({
(config.capabilities as WebdriverIO.Capabilities[]).push({
browserName: 'safari'
})
}
3 changes: 1 addition & 2 deletions packages/devtools/src/commands/newSession.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { v4 as uuidv4 } from 'uuid'

import launch from '../launcher.js'
import { sessionMap } from '../index.js'
import type { ExtendedCapabilities } from '../types.js'
import type DevToolsDriver from '../devtoolsdriver.js'

/**
Expand All @@ -17,7 +16,7 @@ import type DevToolsDriver from '../devtoolsdriver.js'
*/
export default async function newSession (
this: DevToolsDriver,
{ capabilities }: { capabilities: ExtendedCapabilities }
{ capabilities }: { capabilities: WebdriverIO.Capabilities }
) {
const browser = await launch(capabilities)
const sessionId = uuidv4()
Expand Down
15 changes: 5 additions & 10 deletions packages/devtools/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,7 @@ import DevToolsDriver from './devtoolsdriver.js'
import launch from './launcher.js'
import { DEFAULTS, SUPPORTED_BROWSER, VENDOR_PREFIX } from './constants.js'
import { getPrototype, patchDebug } from './utils.js'
import type {
Client,
AttachOptions,
ExtendedCapabilities,
WDIODevtoolsOptions as WDIODevtoolsOptionsExtension
} from './types.js'
import type { Client, AttachOptions, DevToolsOptions as WDIODevtoolsOptionsExtension } from './types.js'

const log = logger('devtools:puppeteer')

Expand Down Expand Up @@ -55,7 +50,7 @@ export default class DevTools {
log.info('Initiate new session using the DevTools protocol')

const requestedCapabilities = { ...params.capabilities }
const browser = await launch(params.capabilities as ExtendedCapabilities)
const browser = await launch(params.capabilities as WebdriverIO.Capabilities)
const pages = await browser.pages()
const driver = new DevToolsDriver(browser, pages)
const sessionId = uuidv4()
Expand All @@ -67,10 +62,10 @@ export default class DevTools {
*/
type ValueOf<T> = T[keyof T]
const availableVendorPrefixes = Object.values(VENDOR_PREFIX)
const vendorCapPrefix = Object.keys(params.capabilities as Capabilities.Capabilities)
const vendorCapPrefix = Object.keys(params.capabilities as WebdriverIO.Capabilities)
.find(
(capKey: ValueOf<typeof VENDOR_PREFIX>) => availableVendorPrefixes.includes(capKey)
) as keyof Capabilities.Capabilities
) as keyof WebdriverIO.Capabilities
||
VENDOR_PREFIX[userAgent.browser.name?.toLocaleLowerCase() as keyof typeof VENDOR_PREFIX]

Expand Down Expand Up @@ -144,7 +139,7 @@ export default class DevTools {
userPrototype = {},
customCommandWrapper?: Function
): Promise<Client> {
const browser = await launch(options.capabilities as ExtendedCapabilities)
const browser = await launch(options.capabilities)
const pages = await browser.pages()
const driver = new DevToolsDriver(browser, pages)
const sessionId = uuidv4()
Expand Down
13 changes: 6 additions & 7 deletions packages/devtools/src/launcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import {
DEFAULT_Y_POSITION,
VENDOR_PREFIX
} from './constants.js'
import type { ExtendedCapabilities, DevToolsOptions } from './types.js'

const log = logger('devtools')

Expand All @@ -32,10 +31,10 @@ const DEVICE_NAMES = Object.keys(KnownDevices)
* @param {object} capabilities session capabilities
* @return {object} puppeteer browser instance
*/
async function launchChrome (capabilities: ExtendedCapabilities) {
async function launchChrome (capabilities: WebdriverIO.Capabilities) {
const chromeOptions: Capabilities.ChromeOptions = capabilities[VENDOR_PREFIX.chrome] || {}
const mobileEmulation = chromeOptions.mobileEmulation || {}
const devtoolsOptions: DevToolsOptions = capabilities['wdio:devtoolsOptions'] || {}
const devtoolsOptions = capabilities['wdio:devtoolsOptions'] || {}
const chromeOptionsArgs = (chromeOptions.args || []).map((arg) => (
arg.startsWith('--') ? arg : `--${arg}`
))
Expand Down Expand Up @@ -147,10 +146,10 @@ async function launchChrome (capabilities: ExtendedCapabilities) {
return browser
}

function launchBrowser (capabilities: ExtendedCapabilities, browserType: 'edge' | 'firefox') {
function launchBrowser (capabilities: WebdriverIO.Capabilities, browserType: 'edge' | 'firefox') {
const product = browserType === BROWSER_TYPE.firefox ? BROWSER_TYPE.firefox : BROWSER_TYPE.chrome
const vendorCapKey = VENDOR_PREFIX[browserType]
const devtoolsOptions: DevToolsOptions = capabilities['wdio:devtoolsOptions'] || {}
const devtoolsOptions = capabilities['wdio:devtoolsOptions'] || {}

/**
* `ignoreDefaultArgs` and `headless` are currently expected to be part of the capabilities
Expand Down Expand Up @@ -205,7 +204,7 @@ function launchBrowser (capabilities: ExtendedCapabilities, browserType: 'edge'
return puppeteer.launch(puppeteerOptions) as unknown as Promise<Browser>
}

function connectBrowser (connectionUrl: string, capabilities: ExtendedCapabilities) {
function connectBrowser (connectionUrl: string, capabilities: WebdriverIO.Capabilities) {
const connectionProp = connectionUrl.startsWith('http') ? 'browserURL' : 'browserWSEndpoint'
const devtoolsOptions = capabilities['wdio:devtoolsOptions']
const options: ConnectOptions = {
Expand All @@ -215,7 +214,7 @@ function connectBrowser (connectionUrl: string, capabilities: ExtendedCapabiliti
return puppeteer.connect(options) as unknown as Promise<Browser>
}

export default async function launch (capabilities: ExtendedCapabilities) {
export default async function launch (capabilities: WebdriverIO.Capabilities) {
try {
Puppeteer.unregisterCustomQueryHandler('shadow')
} catch {
Expand Down
9 changes: 6 additions & 3 deletions packages/devtools/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@ import type { Options, Capabilities } from '@wdio/types'
import type { ProtocolCommands } from '@wdio/protocols'
import type { LaunchOptions, BrowserLaunchArgumentOptions, BrowserConnectOptions, ConnectOptions } from 'puppeteer-core'
import type { EventEmitter as PuppeteerEventEmitter } from 'puppeteer-core/lib/esm/puppeteer/common/EventEmitter.js'
export interface ExtendedCapabilities extends Capabilities.Capabilities, WDIODevtoolsOptions {}

export interface WDIODevtoolsOptions {
'wdio:devtoolsOptions'?: DevToolsOptions
declare global {
namespace WebdriverIO {
interface Capabilities {
'wdio:devtoolsOptions'?: Partial<DevToolsOptions>
}
}
}

export interface DevToolsOptions extends LaunchOptions, BrowserLaunchArgumentOptions, BrowserConnectOptions, ConnectOptions {
Expand Down
32 changes: 16 additions & 16 deletions packages/wdio-browserstack-service/src/accessibility-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class _AccessibilityHandler {
private _accessibilityAutomation?: boolean | string,
private _accessibilityOpts?: { [key: string]: any; }
) {
const caps = (this._browser as WebdriverIO.Browser).capabilities as Capabilities.Capabilities
const caps = (this._browser as WebdriverIO.Browser).capabilities as WebdriverIO.Capabilities

this._platformA11yMeta = {
browser_name: caps.browserName,
Expand All @@ -56,27 +56,27 @@ class _AccessibilityHandler {
_getCapabilityValue(caps: Capabilities.RemoteCapability, capType: string, legacyCapType: string) {
if (caps) {
if (capType === 'accessibility') {
if ((caps as Capabilities.Capabilities)['bstack:options'] && (isTrue((caps as Capabilities.Capabilities)['bstack:options']?.accessibility))) {
return (caps as Capabilities.Capabilities)['bstack:options']?.accessibility
} else if (isTrue((caps as Capabilities.Capabilities)['browserstack.accessibility'])) {
return (caps as Capabilities.Capabilities)['browserstack.accessibility']
if ((caps as WebdriverIO.Capabilities)['bstack:options'] && (isTrue((caps as WebdriverIO.Capabilities)['bstack:options']?.accessibility))) {
return (caps as WebdriverIO.Capabilities)['bstack:options']?.accessibility
} else if (isTrue((caps as WebdriverIO.Capabilities)['browserstack.accessibility'])) {
return (caps as WebdriverIO.Capabilities)['browserstack.accessibility']
}
} else if (capType === 'deviceName') {
if ((caps as Capabilities.Capabilities)['bstack:options'] && (caps as Capabilities.Capabilities)['bstack:options']?.deviceName) {
return (caps as Capabilities.Capabilities)['bstack:options']?.deviceName
} else if ((caps as Capabilities.Capabilities)['bstack:options'] && (caps as Capabilities.Capabilities)['bstack:options']?.device) {
return (caps as Capabilities.Capabilities)['bstack:options']?.device
} else if ((caps as Capabilities.Capabilities)['appium:deviceName']) {
return (caps as Capabilities.Capabilities)['appium:deviceName']
if ((caps as WebdriverIO.Capabilities)['bstack:options'] && (caps as WebdriverIO.Capabilities)['bstack:options']?.deviceName) {
return (caps as WebdriverIO.Capabilities)['bstack:options']?.deviceName
} else if ((caps as WebdriverIO.Capabilities)['bstack:options'] && (caps as WebdriverIO.Capabilities)['bstack:options']?.device) {
return (caps as WebdriverIO.Capabilities)['bstack:options']?.device
} else if ((caps as WebdriverIO.Capabilities)['appium:deviceName']) {
return (caps as WebdriverIO.Capabilities)['appium:deviceName']
}
} else if (capType === 'goog:chromeOptions' && (caps as Capabilities.Capabilities)['goog:chromeOptions']) {
return (caps as Capabilities.Capabilities)['goog:chromeOptions']
} else if (capType === 'goog:chromeOptions' && (caps as WebdriverIO.Capabilities)['goog:chromeOptions']) {
return (caps as WebdriverIO.Capabilities)['goog:chromeOptions']
} else {
const bstackOptions = (caps as Capabilities.Capabilities)['bstack:options']
const bstackOptions = (caps as WebdriverIO.Capabilities)['bstack:options']
if ( bstackOptions && bstackOptions?.[capType as keyof Capabilities.BrowserStackCapabilities]) {
return bstackOptions?.[capType as keyof Capabilities.BrowserStackCapabilities]
} else if ((caps as Capabilities.Capabilities)[legacyCapType as keyof Capabilities.Capabilities]) {
return (caps as Capabilities.Capabilities)[legacyCapType as keyof Capabilities.Capabilities]
} else if ((caps as WebdriverIO.Capabilities)[legacyCapType as keyof WebdriverIO.Capabilities]) {
return (caps as WebdriverIO.Capabilities)[legacyCapType as keyof WebdriverIO.Capabilities]
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions packages/wdio-browserstack-service/src/insights-handler.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import path from 'node:path'

import type { Capabilities, Frameworks } from '@wdio/types'
import type { Frameworks } from '@wdio/types'
import type { BeforeCommandArgs, AfterCommandArgs } from '@wdio/reporter'
import logger from '@wdio/logger'

Expand Down Expand Up @@ -54,7 +54,7 @@ class _InsightsHandler {

constructor (private _browser: WebdriverIO.Browser | WebdriverIO.MultiRemoteBrowser, isAppAutomate?: boolean, private _framework?: string) {
this._requestQueueHandler.start()
const caps = (this._browser as WebdriverIO.Browser).capabilities as Capabilities.Capabilities
const caps = (this._browser as WebdriverIO.Browser).capabilities as WebdriverIO.Capabilities
const sessionId = (this._browser as WebdriverIO.Browser).sessionId

this._platformMeta = {
Expand Down
Loading

0 comments on commit 4277730

Please sign in to comment.