Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make requestedCapabilities better accessible #5351

Merged
merged 7 commits into from
May 5, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 9 additions & 2 deletions docs/BrowserObject.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Besides all commands from the [API](API.md), the `browser` object provides some
console.log(browser.sessionId) // outputs: "57b15c6ea81d0edb9e5b372da3d9ce28"
console.log(browser.capabilities)
/**
* outputs:
* outputs capabilities returned by the browser driver, e.g.:
{ acceptInsecureCerts: false,
acceptSslCerts: false,
applicationCacheEnabled: false,
Expand Down Expand Up @@ -43,11 +43,18 @@ console.log(browser.capabilities)
version: '68.0.3440.106',
webStorageEnabled: true }
*/
console.log(browser.requestedCapabilities)
/**
* outputs original capabilities set by the user, e.g.:
* {
* browserName: 'chrome'
* }
*/
```

## Get Config Options

You can always define custom options within your WDIO config:
If using the WDIO testrunner you can always define custom options within your WDIO config:

```js
// wdio.conf.js
Expand Down
18 changes: 7 additions & 11 deletions packages/devtools/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ export default class DevTools {
const vendorCapPrefix = Object.keys(params.capabilities).find(
(capKey) => availableVendorPrefixes.includes(capKey))

/**
* save original set of capabilities to allow to request the same session again
* (e.g. for reloadSession command in WebdriverIO)
*/
params.requestedCapabilities = { ...params.capabilities }
mgrybyk marked this conversation as resolved.
Show resolved Hide resolved

params.capabilities = {
browserName: userAgent.browser.name,
browserVersion: userAgent.browser.version,
Expand All @@ -52,15 +58,6 @@ export default class DevTools {
)
}

/**
* save original set of capabilities to allow to request the same session again
* (e.g. for reloadSession command in WebdriverIO)
*/
params.requestedCapabilities = {
w3cCaps: params.capabilities,
jsonwpCaps: params.capabilities
}

sessionMap.set(sessionId, { browser, session: driver })
const environmentPrototype = { getPuppeteer: { value: /* istanbul ignore next */ () => browser } }
Object.entries(devtoolsEnvironmentDetector({ browserName: userAgent.browser.name.toLowerCase() })).forEach(([name, value]) => {
Expand All @@ -76,8 +73,7 @@ export default class DevTools {

static async reloadSession (instance) {
const { session } = sessionMap.get(instance.sessionId)
const { w3cCaps } = instance.options.requestedCapabilities
const browser = await launch(w3cCaps)
const browser = await launch(instance.requestedCapabilities)
const pages = await browser.pages()

session.elementStore.clear()
Expand Down
16 changes: 2 additions & 14 deletions packages/devtools/tests/__snapshots__/devtools.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,7 @@ Object {

exports[`newSession 2`] = `
Object {
"jsonwpCaps": Object {
"browserName": "Chrome",
"browserVersion": "80.0.3987.149",
"goog:chromeOptions": Object {
"debuggerAddress": "localhost:49375",
},
},
"w3cCaps": Object {
"browserName": "Chrome",
"browserVersion": "80.0.3987.149",
"goog:chromeOptions": Object {
"debuggerAddress": "localhost:49375",
},
},
"browserName": "chrome",
"goog:chromeOptions": Object {},
}
`;
2 changes: 1 addition & 1 deletion packages/wdio-sync/webdriverio-core.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -827,7 +827,7 @@ declare namespace WebdriverIO {
script?: number
}

interface Browser {
interface Browser extends WebDriver.BaseClient {
config: Config;
options: RemoteOptions;

Expand Down
2 changes: 1 addition & 1 deletion packages/wdio-utils/src/envDetector.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ export function sessionEnvironmentDetector ({ capabilities, requestedCapabilitie
isMobile: isMobile(capabilities),
isIOS: isIOS(capabilities),
isAndroid: isAndroid(capabilities),
isSauce: isSauce(requestedCapabilities.w3cCaps.alwaysMatch),
isSauce: isSauce(requestedCapabilities),
isSeleniumStandalone: isSeleniumStandalone(capabilities)
}
}
Expand Down
5 changes: 5 additions & 0 deletions packages/wdio-utils/src/monad.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,13 @@ export default function WebDriver (options, modifier, propertiesObject = {}) {
* WebDriver monad
*/
function unit (sessionId, commandWrapper) {
/**
* capabilities attached to the instance prototype not being shown if
* logging the instance
*/
propertiesObject.commandList = { value: Object.keys(propertiesObject) }
propertiesObject.options = { value: options }
propertiesObject.requestedCapabilities = { value: options.requestedCapabilities }

/**
* allow to wrap commands if necessary
Expand Down
8 changes: 4 additions & 4 deletions packages/wdio-utils/tests/envDetector.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,18 +51,18 @@ describe('sessionEnvironmentDetector', () => {

it('isSauce', () => {
const capabilities = { browserName: 'chrome' }
let requestedCapabilities = { w3cCaps: { alwaysMatch: {} } }
let requestedCapabilities = {}
let hostname = 'localhost' // isSauce should also be true if run through Sauce Connect

expect(sessionEnvironmentDetector({ capabilities, requestedCapabilities }).isSauce).toBe(false)
expect(sessionEnvironmentDetector({ capabilities, hostname, requestedCapabilities }).isSauce).toBe(false)

requestedCapabilities.w3cCaps.alwaysMatch.extendedDebugging = true
requestedCapabilities.extendedDebugging = true
expect(sessionEnvironmentDetector({ capabilities, hostname, requestedCapabilities }).isSauce).toBe(true)
requestedCapabilities = { w3cCaps: { alwaysMatch: {} } }
requestedCapabilities = {}
expect(sessionEnvironmentDetector({ capabilities, hostname, requestedCapabilities }).isSauce).toBe(false)

requestedCapabilities.w3cCaps.alwaysMatch['sauce:options'] = { extendedDebugging: true }
requestedCapabilities['sauce:options'] = { extendedDebugging: true }
expect(sessionEnvironmentDetector({ capabilities, hostname, requestedCapabilities }).isSauce).toBe(true)
expect(sessionEnvironmentDetector({ capabilities, requestedCapabilities }).isSauce).toBe(true)
})
Expand Down
23 changes: 7 additions & 16 deletions packages/webdriver/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import logger from '@wdio/logger'
import { webdriverMonad, sessionEnvironmentDetector } from '@wdio/utils'
import { validateConfig } from '@wdio/config'

import WebDriverRequest from './request'
import { DEFAULTS } from './constants'
import { startWebDriverSession, getPrototype, getEnvironmentVars, setupDirectConnect } from './utils'

Expand Down Expand Up @@ -60,21 +59,13 @@ export default class WebDriver {
}

static async reloadSession (instance) {
const { w3cCaps, jsonwpCaps } = instance.options.requestedCapabilities
const sessionRequest = new WebDriverRequest(
'POST',
'/session',
{
capabilities: w3cCaps, // W3C compliant
desiredCapabilities: jsonwpCaps // JSONWP compliant
}
)

const response = await sessionRequest.makeRequest(instance.options)
const newSessionId = response.sessionId || (response.value && response.value.sessionId)
instance.sessionId = newSessionId

return newSessionId
const params = {
...instance.options,
capabilities: instance.requestedCapabilities
}
const sessionId = await startWebDriverSession(params)
instance.sessionId = sessionId
return sessionId
}

static get WebDriver () {
Expand Down
2 changes: 1 addition & 1 deletion packages/webdriver/src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export async function startWebDriverSession (params) {
* save original set of capabilities to allow to request the same session again
* (e.g. for reloadSession command in WebdriverIO)
*/
params.requestedCapabilities = { w3cCaps, jsonwpCaps }
params.requestedCapabilities = params.capabilities

/**
* save actual receveived session details
Expand Down
9 changes: 9 additions & 0 deletions packages/webdriver/tests/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,15 @@ describe('WebDriver', () => {

expect(logger.setLevel).toBeCalled()
})

it('propagates capabilities and requestedCapabilities', async () => {
const browser = await WebDriver.newSession({
path: '/',
capabilities: { browserName: 'firefox' }
})
expect(browser.capabilities.browserName).toBe('mockBrowser')
expect(browser.requestedCapabilities.browserName).toBe('firefox')
})
})

describe('attachToSession', () => {
Expand Down
23 changes: 17 additions & 6 deletions packages/webdriver/tests/utils.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -240,14 +240,25 @@ describe('utils', () => {
})

describe('startWebDriverSession', () => {
it('should handle sessionRequest error', async () => {
let error
try {
await startWebDriverSession({})
} catch (err) {
error = err
it('attaches capabilities to the params object', async () => {
const params = {
hostname: 'localhost',
port: 4444,
path: '/',
protocol: 'http',
capabilities: {
browserName: 'chrome',
}
}
const sessionId = await startWebDriverSession(params)
expect(sessionId).toBe('foobar-123')
expect(params.capabilities.browserName).toBe('mockBrowser')
expect(params.requestedCapabilities.browserName).toBe('chrome')

})

it('should handle sessionRequest error', async () => {
let error = await startWebDriverSession({}).catch((err) => err)
expect(error.message).toContain('Failed to create session')
})
})
Expand Down
38 changes: 29 additions & 9 deletions packages/webdriver/webdriver.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,7 @@ declare namespace WebDriver {
* Defines the [capabilities](https://w3c.github.io/webdriver/webdriver-spec.html#capabilities) you want to run in your Selenium session.
*/
capabilities?: DesiredCapabilities;
requestedCapabilities?: DesiredCapabilities;
/**
* Level of logging verbosity.
*/
Expand Down Expand Up @@ -610,9 +611,28 @@ declare namespace WebDriver {
mjpegScalingFactor?: number,
}

interface BaseClient {
// id of WebDriver session
sessionId: string;
// assigned capabilities by the browser driver / WebDriver server
capabilities: DesiredCapabilities;
// original requested capabilities
requestedCapabilities: DesiredCapabilities;

/**
* browser flags
*/
// true if session runs on a mobile device
isMobile: boolean;
// true if mobile session runs on iOS
isIOS: boolean;
// true if mobile session runs on Android
isAndroid: boolean;
}

// generated typings
// webdriver types
interface Client {
interface Client extends BaseClient {

/**
* [webdriver]
Expand Down Expand Up @@ -1008,7 +1028,7 @@ declare namespace WebDriver {
}

// appium types
interface Client {
interface Client extends BaseClient {

/**
* [appium]
Expand Down Expand Up @@ -1446,7 +1466,7 @@ declare namespace WebDriver {
}

// jsonwp types
interface Client {
interface Client extends BaseClient {

/**
* [jsonwp]
Expand Down Expand Up @@ -2115,7 +2135,7 @@ declare namespace WebDriver {
}

// mjsonwp types
interface Client {
interface Client extends BaseClient {

/**
* [mjsonwp]
Expand Down Expand Up @@ -2182,7 +2202,7 @@ declare namespace WebDriver {
}

// chromium types
interface Client {
interface Client extends BaseClient {

/**
* [chromium]
Expand Down Expand Up @@ -2354,7 +2374,7 @@ declare namespace WebDriver {
}

// saucelabs types
interface Client {
interface Client extends BaseClient {

/**
* [saucelabs]
Expand Down Expand Up @@ -2400,7 +2420,7 @@ declare namespace WebDriver {
}

// selenium types
interface Client {
interface Client extends BaseClient {

/**
* [selenium]
Expand Down Expand Up @@ -2439,11 +2459,11 @@ declare namespace WebDriver {
}


interface ClientAsync extends AsyncClient { }
interface ClientAsync extends AsyncClient, BaseClient { }
}

type AsyncClient = {
[K in keyof WebDriver.Client]:
[K in keyof Pick<WebDriver.Client, Exclude<keyof WebDriver.Client, keyof WebDriver.BaseClient>>]:
(...args: Parameters<WebDriver.Client[K]>) => Promise<ReturnType<WebDriver.Client[K]>>;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ describe('reloadSession test', () => {
name: 'should be sessionId if sessionId and value.sessionId are present',
sessionIdMock: 'foobar-456',
requestMock: [{}, { sessionId: 'foobar-567' }],
newSessionId: 'foobar-456',
newSessionId: 'foobar-567',
jsonwpMode: true
}]

Expand Down
2 changes: 1 addition & 1 deletion packages/webdriverio/webdriverio-core.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -827,7 +827,7 @@ declare namespace WebdriverIO {
script?: number
}

interface Browser {
interface Browser extends WebDriver.BaseClient {
config: Config;
options: RemoteOptions;

Expand Down