Skip to content

Commit

Permalink
Fixes #6057 (#6066)
Browse files Browse the repository at this point in the history
  • Loading branch information
vmelikyan committed Nov 17, 2020
1 parent 91a6d92 commit df76185
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 7 deletions.
32 changes: 26 additions & 6 deletions packages/webdriverio/src/commands/browser/mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ import DevtoolsNetworkInterception from '../../utils/interception/devtools'
import WebDriverNetworkInterception from '../../utils/interception/webdriver'
import { getBrowserObject } from '../../utils'

const SESSION_MOCKS: Set<Interception> = new Set()
const SESSION_MOCKS: Record<string, Set<Interception>> = {}

export default async function mock (this: WebdriverIO.BrowserObject, url: string, filterOptions: WebdriverIO.MockFilterOptions) {
const NetworkInterception = this.isSauce ? WebDriverNetworkInterception : DevtoolsNetworkInterception
Expand All @@ -109,25 +109,45 @@ export default async function mock (this: WebdriverIO.BrowserObject, url: string
await this.getPuppeteer()
}

const browser = getBrowserObject(this)
const handle = await browser.getWindowHandle()
if (!SESSION_MOCKS[handle]) {
SESSION_MOCKS[handle] = new Set()
}

/**
* enable network Mocking if not already
*/
if (SESSION_MOCKS.size === 0 && !this.isSauce) {
const [page] = await this.puppeteer.pages()
if (SESSION_MOCKS[handle].size === 0 && !this.isSauce) {
const pages = await this.puppeteer.pages()

// get active page
let page
for (let i = 0; i < pages.length && !page; i++) {
const isHidden = await pages[i].evaluate(() => document.hidden)
if (!isHidden) {
page = pages[i]
}
}

// fallback to the first page
if (!page) {
page = pages[0]
}

const client = await page.target().createCDPSession()
await client.send('Fetch.enable', {
patterns: [{ requestStage: 'Request' }, { requestStage: 'Response' }]
})
client.on(
'Fetch.requestPaused',
(NetworkInterception as unknown as typeof DevtoolsNetworkInterception)
.handleRequestInterception(client, SESSION_MOCKS)
.handleRequestInterception(client, SESSION_MOCKS[handle])
)
}

const browser = getBrowserObject(this)
const networkInterception = new NetworkInterception(url, filterOptions, browser)
SESSION_MOCKS.add(networkInterception as Interception)
SESSION_MOCKS[handle].add(networkInterception as Interception)

if (this.isSauce) {
await (networkInterception as WebDriverNetworkInterception).init()
Expand Down
3 changes: 3 additions & 0 deletions packages/webdriverio/tests/__mocks__/got.js
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,9 @@ const requestMock = jest.fn().mockImplementation((uri, params) => {
case `${path}/${sessionId}/window/handles`:
value = ['window-handle-1', 'window-handle-2', 'window-handle-3']
break
case `${path}/${sessionId}/window`:
value = 'window-handle-1'
break
case `${path}/${sessionId}/url`:
value = 'https://webdriver.io/?foo=bar'
break
Expand Down
29 changes: 28 additions & 1 deletion packages/webdriverio/tests/commands/browser/mock.test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import got from 'got'
import { remote } from '../../../src'

const clientMock = {
Expand All @@ -7,7 +8,8 @@ const clientMock = {
const pageMock = {
target: jest.fn().mockReturnValue({
createCDPSession: jest.fn().mockReturnValue(Promise.resolve(clientMock))
})
}),
evaluate: jest.fn().mockReturnValue(Promise.resolve(true))
}
const puppeteerMock = {
pages: jest.fn().mockReturnValue([pageMock])
Expand All @@ -21,6 +23,9 @@ jest.mock('../../../src/utils/interception/webdriver', () => class WebDriverInte

describe('custom$', () => {
let browser
beforeEach(async () => {
clientMock.send.mockClear()
})

it('should enable the fetch domain if not already done', async () => {
browser = await remote({
Expand All @@ -41,6 +46,28 @@ describe('custom$', () => {
expect(clientMock.send).toBeCalledTimes(1)
})

it('should mock on multiple tabs', async () => {
browser = await remote({
baseUrl: 'http://foobar.com',
capabilities: {
browserName: 'devtools'
}
})

browser.puppeteer = puppeteerMock

got.setMockResponse('window-handle-2')
expect(clientMock.send).toBeCalledTimes(0)
await browser.mock('/foobar')
expect(clientMock.send).toBeCalledTimes(1)
expect(clientMock.send).toBeCalledWith('Fetch.enable', expect.any(Object))
expect(clientMock.on).toBeCalledWith('Fetch.requestPaused', expect.any(Function))
got.setMockResponse('window-handle-3')
await browser.mock('/foobar')
expect(clientMock.send).toBeCalledTimes(2)

})

it('should mock using WebDriver capabilities', async () => {
browser = await remote({
baseUrl: 'http://foobar.com',
Expand Down

0 comments on commit df76185

Please sign in to comment.