Skip to content

Commit

Permalink
webdriver: support rebinding of context when invoking origFn in… (#4186)
Browse files Browse the repository at this point in the history
  • Loading branch information
akloeber authored and christian-bromann committed Jul 15, 2019
1 parent 6e72209 commit fd1bfd2
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 2 deletions.
4 changes: 4 additions & 0 deletions packages/wdio-webdriver-mock-service/src/index.js
Expand Up @@ -6,6 +6,7 @@ import { newSession, deleteSession } from './mocks/newSession'

const ELEMENT_ID = '401c0039-3306-6a46-a98d-f5939870a249'
const ELEMENT_REFETCHED = '80d860d0-b829-f540-812e-7078eb983795'
const ELEMENT_ALT = '8bf4d107-a363-40d1-b823-d94bdbc58afb'
newSession.value.sessionId = SESSION_ID

export default class WebdriverMockService {
Expand All @@ -23,6 +24,7 @@ export default class WebdriverMockService {
this.command.getTitle().times(2).reply(200, { value: 'Mock Page Title' })
this.command.getUrl().times(2).reply(200, { value: 'https://mymockpage.com' })
this.command.getElementRect(ELEMENT_ID).times(2).reply(200, { value: { width: 1, height: 2, x: 3, y: 4 } })
this.command.getElementRect(ELEMENT_ALT).times(2).reply(200, { value: { width: 10, height: 20, x: 30, y: 40 } })
this.command.getLogTypes().reply(200, { value: [] })
}

Expand Down Expand Up @@ -109,7 +111,9 @@ export default class WebdriverMockService {
this.nockReset()

const elemResponse = { 'element-6066-11e4-a52e-4f735466cecf': ELEMENT_ID }
const elemAltResponse = { 'element-6066-11e4-a52e-4f735466cecf': ELEMENT_ALT }
this.command.findElement().times(times).reply(200, { value: elemResponse })
this.command.findElement().times(times).reply(200, { value: elemAltResponse })
this.command.executeScript().times(times).reply(200, { value: '2' })

// overwrite
Expand Down
9 changes: 8 additions & 1 deletion packages/webdriver/src/utils.js
Expand Up @@ -382,7 +382,14 @@ export function overwriteElementCommands(propertiesObject) {
delete propertiesObject[commandName]

const newCommand = function (...args) {
return userDefinedCommand.apply(this, [origCommand.bind(this), ...args])
const element = this
return userDefinedCommand.apply(element, [
function origCommandFunction() {
const context = this || element // respect explicite context binding, use element as default
return origCommand.apply(context, arguments)
},
...args
])
}

propertiesObject[commandName] = {
Expand Down
21 changes: 20 additions & 1 deletion packages/webdriver/tests/utils.test.js
Expand Up @@ -290,14 +290,33 @@ describe('utils', () => {
describe('overwriteElementCommands', () => {
it('should overwrite command', function () {
const context = {}
const origFnMock = jest.fn(() => 1)
const propertiesObject = {
foo: { value() { return 1 } },
foo: { value: origFnMock },
__elementOverrides__: {
value: { foo(origCmd, arg) { return [origCmd(), arg] } }
}
}
overwriteElementCommands.call(context, propertiesObject)
expect(propertiesObject.foo.value(5)).toEqual([1, 5])
expect(origFnMock.mock.calls.length).toBe(1)
expect(origFnMock.mock.instances[0]).toBe(propertiesObject.foo)
})

it('should support rebinding when invoking original fn', function () {
const context = {}
const origFnMock = jest.fn(() => 1)
const origFnContext = {}
const propertiesObject = {
foo: { value: origFnMock },
__elementOverrides__: {
value: { foo(origCmd, arg) { return [origCmd.call(origFnContext), arg] } }
}
}
overwriteElementCommands.call(context, propertiesObject)
expect(propertiesObject.foo.value(5)).toEqual([1, 5])
expect(origFnMock.mock.calls.length).toBe(1)
expect(origFnMock.mock.instances[0]).toBe(origFnContext)
})

it('should create __elementOverrides__ if not exists', function () {
Expand Down
15 changes: 15 additions & 0 deletions tests/mocha/test.js
Expand Up @@ -149,6 +149,21 @@ describe('Mocha smoke test', () => {
)
})

it('should allow to invoke native command on different element', () => {
browser.customCommandScenario()
browser.overwriteCommand('getSize', function (origCommand, ratio = 1) {
const elemAlt = $('elemAlt')
const { width, height } = origCommand.call(elemAlt)
return { width: width * ratio, height: height * ratio }
}, true)
const elem = $('elem')

assert.equal(
JSON.stringify(elem.getSize(2)),
JSON.stringify({ width: 20, height: 40 })
)
})

it('should keep the scope', () => {
browser.customCommandScenario()
browser.overwriteCommand('saveRecordingScreen', function (origCommand, filepath, elem) {
Expand Down

0 comments on commit fd1bfd2

Please sign in to comment.