Skip to content

Commit

Permalink
allow sync assertions in async context (#7467)
Browse files Browse the repository at this point in the history
  • Loading branch information
christian-bromann committed Sep 23, 2021
1 parent 30c3b6c commit c62eea7
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 3 deletions.
35 changes: 33 additions & 2 deletions packages/wdio-utils/src/shim.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,37 @@ declare global {
}
}

/**
* Jasmine differentiates between sync and async matchers.
* In order to offer a consistent experience WebdriverIO is
* replacing `expect` with `expectAsync` in every spec file
* that is async. Now to also allow assertions of literal values
* like string, numbers etc. in an async function we overwrite expect
* with this shim to check the input value. If we assert a promise,
* a browser or element object we use `expectAsync` otherwise the
* normal sync `expect`.
*
* Note: `syncMatcher` as parameter is only for testing purposes
*/
let expectSync: Function
export function expectAsyncShim (actual?: any, syncMatcher = expectSync) {
const expectAsync = global.expectAsync
const useSync = (
!actual ||
(
typeof actual.then !== 'function' &&
!actual.sessionId &&
!actual.elementId
)
)

if (useSync) {
return syncMatcher(actual)
}

return expectAsync(actual)
}

const ELEMENT_QUERY_COMMANDS = ['$', '$$', 'custom$', 'custom$$', 'shadow$', 'shadow$$', 'react$', 'react$$']
const ELEMENT_PROPS = ['elementId', 'error', 'selector', 'parent', 'index', 'isReactElement', 'length']
const PROMISE_METHODS = ['then', 'catch', 'finally']
Expand Down Expand Up @@ -353,9 +384,9 @@ async function executeAsync(this: any, fn: Function, retries: Retries, args: any
const asyncSpecBefore = asyncSpec
this.wdioRetries = retries.attempts

const expectSync = global.expect
expectSync = global.expect
if (isJasmine) {
global.expect = global.expectAsync
global.expect = expectAsyncShim
}

try {
Expand Down
22 changes: 21 additions & 1 deletion packages/wdio-utils/tests/shim.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { wrapCommand, switchSyncFlag, runAsync } from '../src/shim'
import { wrapCommand, switchSyncFlag, runAsync, expectAsyncShim } from '../src/shim'

describe('wrapCommand', () => {
it('should run command with before and after hook', async () => {
Expand Down Expand Up @@ -94,3 +94,23 @@ describe('switchSyncFlag', () => {
expect(runAsync).toBe(true)
})
})

test('expectAsyncShim', () => {
global.expectAsync = jest.fn()
const expectSync = jest.fn()
expectAsyncShim(undefined, expectSync)
expect(expectSync).toBeCalledTimes(1)
expect(global.expectAsync).toBeCalledTimes(0)
expectAsyncShim(42, expectSync)
expect(expectSync).toBeCalledTimes(2)
expect(global.expectAsync).toBeCalledTimes(0)
expectAsyncShim(Promise.resolve({}), expectSync)
expect(expectSync).toBeCalledTimes(2)
expect(global.expectAsync).toBeCalledTimes(1)
expectAsyncShim({ elementId: 42 }, expectSync)
expect(expectSync).toBeCalledTimes(2)
expect(global.expectAsync).toBeCalledTimes(2)
expectAsyncShim({ sessionId: '42' }, expectSync)
expect(expectSync).toBeCalledTimes(2)
expect(global.expectAsync).toBeCalledTimes(3)
})
14 changes: 14 additions & 0 deletions tests/jasmine/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,24 @@ describe('Jasmine smoke test', () => {
expect($('foo')).toBeDisplayed()
})

it('should allow sync matchers', () => {
const test = 123
expect(test).toBe(123)
})

it('should return async value', async () => {
browser.isEventuallyDisplayedScenario()
await expect(browser).toHaveTitle('Mock Page Title')
await expect($('foo')).toBeDisplayed()

browser.isEventuallyDisplayedScenario()
const elem = $('foo')
await expect(elem).toBeDisplayed()
})

it('should allow sync assertion in async context', async () => {
const test = 123
expect(test).toBe(123)
})

let hasRun = false
Expand Down

0 comments on commit c62eea7

Please sign in to comment.