模拟对象
模拟对象是一个表示网络模拟的对象,包含有关与给定url
和filterOptions
匹配的请求的信息。可以使用mock
命令接收它。
信息
请注意,使用mock
命令需要支持 Chrome DevTools 协议。如果您在基于 Chromium 的浏览器中本地运行测试,或者您使用 Selenium Grid v4 或更高版本,则会提供该支持。在云端运行自动化测试时,**不能**使用此命令。在自动化协议部分中了解更多信息。
您可以在我们的模拟和间谍指南中阅读更多关于在 WebdriverIO 中模拟请求和响应的信息。
属性
模拟对象包含以下属性
名称 | 类型 | 详情 |
---|---|---|
url | 字符串 | 传递给模拟命令的 url |
filterOptions | 对象 | 传递给模拟命令的资源过滤器选项 |
浏览器 | 对象 | 用于获取模拟对象的浏览器对象。 |
calls | 对象[] | 有关匹配浏览器请求的信息,包含诸如url 、method 、headers 、initialPriority 、referrerPolic 、statusCode 、responseHeaders 和body 等属性 |
方法
模拟对象提供了各种命令(在mock
部分列出),允许用户修改请求或响应的行为。
事件
模拟对象是一个 EventEmitter,并且为您的用例发出了几个事件。
以下是事件列表。
request
当启动与模拟模式匹配的网络请求时,会发出此事件。请求在事件回调中传递。
请求接口
interface RequestEvent {
requestId: number
request: Matches
responseStatusCode: number
responseHeaders: Record<string, string>
}
overwrite
当使用respond
或respondOnce
覆盖网络响应时,会发出此事件。响应在事件回调中传递。
响应接口
interface OverwriteEvent {
requestId: number
responseCode: number
responseHeaders: Record<string, string>
body?: string | Record<string, any>
}
fail
当使用abort
或abortOnce
中止网络请求时,会发出此事件。失败在事件回调中传递。
失败接口
interface FailEvent {
requestId: number
errorReason: Protocol.Network.ErrorReason
}
match
在continue
或overwrite
之前,添加新匹配项时会发出此事件。匹配项在事件回调中传递。
匹配接口
interface MatchEvent {
url: string // Request URL (without fragment).
urlFragment?: string // Fragment of the requested URL starting with hash, if present.
method: string // HTTP request method.
headers: Record<string, string> // HTTP request headers.
postData?: string // HTTP POST request data.
hasPostData?: boolean // True when the request has POST data.
mixedContentType?: MixedContentType // The mixed content export type of the request.
initialPriority: ResourcePriority // Priority of the resource request at the time request is sent.
referrerPolicy: ReferrerPolicy // The referrer policy of the request, as defined in https://www.w3.org/TR/referrer-policy/
isLinkPreload?: boolean // Whether is loaded via link preload.
body: string | Buffer | JsonCompatible // Body response of actual resource.
responseHeaders: Record<string, string> // HTTP response headers.
statusCode: number // HTTP response status code.
mockedResponse?: string | Buffer // If mock, emitting the event, also modified it's response.
}
continue
当网络响应既未被覆盖也未被中断,或者响应已由另一个模拟发送时,会发出此事件。requestId
在事件回调中传递。
示例
获取挂起的请求数量
let pendingRequests = 0
const mock = await browser.mock('**') // it is important to match all requests otherwise, the resulting value can be very confusing.
mock.on('request', ({request}) => {
pendingRequests++
console.log(`matched request to ${request.url}, pending ${pendingRequests} requests`)
})
mock.on('match', ({url}) => {
pendingRequests--
console.log(`resolved request to ${url}, pending ${pendingRequests} requests`)
})
在 404 网络失败时抛出错误
browser.addCommand('loadPageWithout404', (url, {selector, predicate}) => new Promise(async (resolve, reject) => {
const mock = await this.mock('**')
mock.on('match', ({url, statusCode}) => {
if (statusCode === 404) {
reject(new Error(`request to ${url} failed with "Not Found"`))
}
})
await this.url(url).catch(reject)
// waiting here, because some requests can still be pending
if (selector) {
await this.$(selector).waitForExist().catch(reject)
}
if (predicate) {
await this.waitUntil(predicate).catch(reject)
}
resolve()
}))
await browser.loadPageWithout404(browser, 'some/url', { selector: 'main' })
确定是否使用了模拟响应值
const firstMock = await browser.mock('**/foo/**')
const secondMock = await browser.mock('**/foo/bar/**')
firstMock.respondOnce({id: 3, title: 'three'})
secondMock.respond({id: 4, title: 'four'})
firstMock.on('overwrite', () => {
// triggers for first request to '**/foo/**'
}).on('continue', () => {
// triggers for rest requests to '**/foo/**'
})
secondMock.on('continue', () => {
// triggers for first request to '**/foo/bar/**'
}).on('overwrite', () => {
// triggers for rest requests to '**/foo/bar/**'
})
在此示例中,firstMock
首先定义,并且有一个respondOnce
调用,因此secondMock
响应值不会用于第一个请求,但将用于其余请求。