跳到主要內容

模擬

透過 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)"

您可以透過呼叫 setSystemTimetick 來修改系統時間。

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 維護一份 所有已定義裝置 的固定清單。

歡迎!我能幫上什麼忙嗎?

WebdriverIO AI Copilot