模拟
使用 WebdriverIO,您可以使用emulate
命令模拟 Web API 以返回自定义值,帮助您模拟某些浏览器行为。请注意,这需要您的应用程序显式使用这些 API。
此功能需要浏览器支持 WebDriver Bidi。虽然 Chrome、Edge 和 Firefox 的最新版本都支持此功能,但 Safari **不支持**。有关更新,请关注wpt.fyi。此外,如果您使用云供应商来生成浏览器,请确保您的供应商也支持 WebDriver Bidi。
要为您的测试启用 WebDriver Bidi,请确保在您的功能中设置了webSocketUrl: true
。
地理位置
将浏览器地理位置更改为特定区域,例如:
await browser.emulate('geolocation', {
latitude: 52.52,
longitude: 13.39,
accuracy: 100
})
await browser.url('https://www.google.com/maps')
await browser.$('aria/Show Your Location').click()
await browser.pause(5000)
console.log(await browser.getUrl()) // outputs: "https://www.google.com/maps/@52.52,13.39,16z?entry=ttu"
这将修补navigator.geolocation.getCurrentPosition
的工作方式,并返回您提供的地理位置。
配色方案
通过以下方式更改浏览器的默认配色方案设置:
await browser.emulate('colorScheme', 'light')
await browser.url('https://webdriverio.node.org.cn')
const backgroundColor = await browser.$('nav').getCSSProperty('background-color')
console.log(backgroundColor.parsed.hex) // outputs: "#efefef"
await browser.emulate('colorScheme', 'dark')
await browser.url('https://webdriverio.node.org.cn')
const backgroundColor = await browser.$('nav').getCSSProperty('background-color')
console.log(backgroundColor.parsed.hex) // outputs: "#000000"
这将修补window.matchMedia
在您通过(prefers-color-scheme: dark)
查询配色方案时的行为。
用户代理
通过以下方式将浏览器的用户代理更改为不同的字符串:
await browser.emulate('userAgent', 'Chrome/1.2.3.4 Safari/537.36')
这将更改navigator.userAgent
的值。请注意,浏览器供应商正在逐步弃用用户代理。
onLine 属性
通过以下方式更改浏览器的在线状态:
await browser.emulate('onLine', false)
这**不会**关闭浏览器与互联网之间的网络流量,只会更改navigator.onLine
的返回值。如果您有兴趣修改浏览器的网络功能,请查看throttleNetwork
命令。
时钟
您可以使用emulate
命令修改浏览器系统时钟。它覆盖了与时间相关的本地全局函数,允许通过clock.tick()
或生成的时钟对象以同步方式控制它们。这包括控制
setTimeout
clearTimeout
setInterval
clearInterval
日期对象
时钟从 Unix 纪元开始(时间戳为 0)。这意味着,如果您在应用程序中实例化新的 Date,如果未向emulate
命令传递任何其他选项,则其时间将为 1970 年 1 月 1 日。
示例
调用browser.emulate('clock', { ... })
时,它将立即覆盖当前页面以及所有后续页面的全局函数,例如:
const clock = await browser.emulate('clock', { now: new Date(1989, 7, 4) })
console.log(await browser.execute(() => (new Date()).toString()))
// returns "Fri Aug 04 1989 00:00:00 GMT-0700 (Pacific Daylight Time)"
await browser.url('https://webdriverio')
console.log(await browser.execute(() => (new Date()).toString()))
// returns "Fri Aug 04 1989 00:00:00 GMT-0700 (Pacific Daylight Time)"
await clock.restore()
console.log(await browser.execute(() => (new Date()).toString()))
// returns "Thu Aug 01 2024 17:59:59 GMT-0700 (Pacific Daylight Time)"
await browser.url('http://guinea-pig.webdriver.io/pointer.html')
console.log(await browser.execute(() => (new Date()).toString()))
// returns "Thu Aug 01 2024 17:59:59 GMT-0700 (Pacific Daylight Time)"
您可以通过调用setSystemTime
或tick
来修改系统时间。
FakeTimerInstallOpts
对象可以具有以下属性
interface FakeTimerInstallOpts {
// Installs fake timers with the specified unix epoch
// @default: 0
now?: number | Date | undefined;
// An array with names of global methods and APIs to fake. By default, WebdriverIO
// does not replace `nextTick()` and `queueMicrotask()`. For instance,
// `browser.emulate('clock', { toFake: ['setTimeout', 'nextTick'] })` will fake only
// `setTimeout()` and `nextTick()`
toFake?: FakeMethod[] | undefined;
// The maximum number of timers that will be run when calling runAll() (default: 1000)
loopLimit?: number | undefined;
// Tells WebdriverIO to increment mocked time automatically based on the real system
// time shift (e.g. the mocked time will be incremented by 20ms for every 20ms change
// in the real system time)
// @default false
shouldAdvanceTime?: boolean | undefined;
// Relevant only when using with shouldAdvanceTime: true. increment mocked time by
// advanceTimeDelta ms every advanceTimeDelta ms change in the real system time
// @default: 20
advanceTimeDelta?: number | undefined;
// Tells FakeTimers to clear 'native' (i.e. not fake) timers by delegating to their
// respective handlers. These are not cleared by default, leading to potentially
// unexpected behavior if timers existed prior to installing FakeTimers.
// @default: false
shouldClearNativeTimers?: boolean | undefined;
}
设备
emulate
命令还支持通过更改视口、设备缩放因子和用户代理来模拟特定的移动或桌面设备。这绝不能用于移动测试,因为桌面浏览器引擎与移动浏览器引擎不同。仅当您的应用程序为较小的视口尺寸提供特定行为时,才应使用此功能。
例如,要将用户代理和视口切换到 iPhone 15,只需运行以下命令:
const restore = await browser.emulate('iPhone 15')
// test your application ...
// reset to original viewport and user agent
await restore()
WebdriverIO 维护了一个所有已定义设备的固定列表。