模擬
透過 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.dev.org.tw')
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.dev.org.tw')
const backgroundColor = await browser.$('nav').getCSSProperty('background-color')
console.log(backgroundColor.parsed.hex) // outputs: "#000000"
當您透過 (prefers-color-scheme: dark)
查詢色彩配置時,這會對 window.matchMedia
的行為進行猴子修補。
使用者代理
透過以下方式將瀏覽器的使用者代理變更為不同的字串:
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
Date 物件
時鐘從 Unix Epoch(時間戳記為 0)開始。這表示如果您不在 emulate
命令中傳遞任何其他選項,當您在應用程式中建立新的 Date 時,其時間會是 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 維護一份 所有已定義裝置 的固定清單。