UNPKG

@luminati-io/webdriverio8

Version:

Next-gen browser and mobile automation test framework for Node.js

128 lines (127 loc) 7.35 kB
/** * WebdriverIO allows you to emulate Web APIs using the `emulate` command. These Web APIs can then * behave exactly as you specify it. * * Read more on this in the [Emulation](/docs/emulation) guidelines. * * :::info * * This feature requires WebDriver Bidi support for the browser. While recent versions of Chrome, Edge * and Firefox have such support, Safari __does not__. For updates follow [wpt.fyi](https://wpt.fyi/results/webdriver/tests/bidi/script/add_preload_script/add_preload_script.py?label=experimental&label=master&aligned). * Furthermore if you use a cloud vendor for spawning browsers, make sure your vendor also supports WebDriver Bidi. * * ::: * * <example> :emulateColorScheme.js it('should open WebdriverIO using light color scheme', async () => { await browser.emulate('colorScheme', 'light') await browser.url('https://webdriver.io') const backgroundColor = await browser.$('nav').getCSSProperty('background-color') console.log(backgroundColor.parsed.hex) // outputs: "#efefef" }) it('should open WebdriverIO using dark color scheme'm async () => { await browser.emulate('colorScheme', 'dark') await browser.url('https://webdriver.io') const backgroundColor = await browser.$('nav').getCSSProperty('background-color') console.log(backgroundColor.parsed.hex) // outputs: "#000000" }) * </example> * * <example> :emulateGeoLocation.js it('should find my emulated geo location', async () => { 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" }) * </example> * * @param {string} scope feature of the browser you like to emulate, can be either `geolocation`, `userAgent`, `colorScheme` or `onLine` * @param {EmulationOptions} options emulation option for specific scope * @returns `void` */ export async function emulate(scope, options) { if (!this.isBidi) { throw new Error('emulate command is only supported for Bidi'); } if (scope === 'geolocation') { if (!options) { throw new Error('Missing geolocation emulation options'); } const patchedFn = options instanceof Error ? `cbError(new Error(${JSON.stringify(options.message)}))` : `cbSuccess({ coords: ${JSON.stringify(options)}, timestamp: Date.now() })`; await this.scriptAddPreloadScript({ functionDeclaration: /*js*/ `() => { Object.defineProperty(navigator.geolocation, 'getCurrentPosition', { value: (cbSuccess, cbError) => ${patchedFn} }) }` }); return; } if (scope === 'userAgent') { if (typeof options !== 'string') { throw new Error(`Expected userAgent emulation options to be a string, received ${typeof options}`); } await this.scriptAddPreloadScript({ functionDeclaration: /*js*/ `() => { Object.defineProperty(navigator, 'userAgent', { value: ${JSON.stringify(options)} }) }` }); return; } if (scope === 'colorScheme') { if (options !== 'light' && options !== 'dark') { throw new Error(`Expected "colorScheme" emulation options to be either "light" or "dark", received "${options}"`); } await this.scriptAddPreloadScript({ functionDeclaration: /*js*/ `() => { const originalMatchMedia = window.matchMedia Object.defineProperty(window, 'matchMedia', { value: (query) => { const colorSchemeQuery = query.match(/\\(prefers-color-scheme:(\\s)*(dark|light)\\)/i) if (colorSchemeQuery) { const result = originalMatchMedia(query) Object.defineProperty(result, 'matches', { value: colorSchemeQuery[2] === "${options}", configurable: true }) return result } return originalMatchMedia(query) }, configurable: true }) }` }); return; } if (scope === 'onLine') { if (typeof options !== 'boolean') { throw new Error(`Expected "onLine" emulation options to be a boolean, received "${typeof options}"`); } await this.scriptAddPreloadScript({ functionDeclaration: /*js*/ `() => { Object.defineProperty(navigator, 'onLine', { value: ${options} }) }` }); return; } return; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW11bGF0ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jb21tYW5kcy9icm93c2VyL2VtdWxhdGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBU0E7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQWdERztBQUNILE1BQU0sQ0FBQyxLQUFLLFVBQVUsT0FBTyxDQUV6QixLQUFZLEVBQ1osT0FBZ0M7SUFFaEMsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNmLE1BQU0sSUFBSSxLQUFLLENBQUMsNENBQTRDLENBQUMsQ0FBQTtJQUNqRSxDQUFDO0lBRUQsSUFBSSxLQUFLLEtBQUssYUFBYSxFQUFFLENBQUM7UUFDMUIsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ1gsTUFBTSxJQUFJLEtBQUssQ0FBQyx1Q0FBdUMsQ0FBQyxDQUFBO1FBQzVELENBQUM7UUFFRCxNQUFNLFNBQVMsR0FBRyxPQUFPLFlBQVksS0FBSztZQUN0QyxDQUFDLENBQUMscUJBQXFCLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJO1lBQzFELENBQUMsQ0FBQzswQkFDWSxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQzs7ZUFFbEMsQ0FBQTtRQUNQLE1BQU0sSUFBSSxDQUFDLHNCQUFzQixDQUFDO1lBQzlCLG1CQUFtQixFQUFFLE1BQU0sQ0FBQTs7cURBRWMsU0FBUzs7Y0FFaEQ7U0FDTCxDQUFDLENBQUE7UUFDRixPQUFNO0lBQ1YsQ0FBQztJQUVELElBQUksS0FBSyxLQUFLLFdBQVcsRUFBRSxDQUFDO1FBQ3hCLElBQUksT0FBTyxPQUFPLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDOUIsTUFBTSxJQUFJLEtBQUssQ0FBQyxpRUFBaUUsT0FBTyxPQUFPLEVBQUUsQ0FBQyxDQUFBO1FBQ3RHLENBQUM7UUFFRCxNQUFNLElBQUksQ0FBQyxzQkFBc0IsQ0FBQztZQUM5QixtQkFBbUIsRUFBRSxNQUFNLENBQUE7OzZCQUVWLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDOztjQUV0QztTQUNMLENBQUMsQ0FBQTtRQUNGLE9BQU07SUFDVixDQUFDO0lBRUQsSUFBSSxLQUFLLEtBQUssYUFBYSxFQUFFLENBQUM7UUFDMUIsSUFBSSxPQUFPLEtBQUssT0FBTyxJQUFJLE9BQU8sS0FBSyxNQUFNLEVBQUUsQ0FBQztZQUM1QyxNQUFNLElBQUksS0FBSyxDQUFDLHNGQUFzRixPQUFPLEdBQUcsQ0FBQyxDQUFBO1FBQ3JILENBQUM7UUFFRCxNQUFNLElBQUksQ0FBQyxzQkFBc0IsQ0FBQztZQUM5QixtQkFBbUIsRUFBRSxNQUFNLENBQUE7Ozs7Ozs7O2tFQVEyQixPQUFPOzs7Ozs7Ozs7O2NBVTNEO1NBQ0wsQ0FBQyxDQUFBO1FBQ0YsT0FBTTtJQUNWLENBQUM7SUFFRCxJQUFJLEtBQUssS0FBSyxRQUFRLEVBQUUsQ0FBQztRQUNyQixJQUFJLE9BQU8sT0FBTyxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQy9CLE1BQU0sSUFBSSxLQUFLLENBQUMsa0VBQWtFLE9BQU8sT0FBTyxHQUFHLENBQUMsQ0FBQTtRQUN4RyxDQUFDO1FBRUQsTUFBTSxJQUFJLENBQUMsc0JBQXNCLENBQUM7WUFDOUIsbUJBQW1CLEVBQUUsTUFBTSxDQUFBOzs2QkFFVixPQUFPOztjQUV0QjtTQUNMLENBQUMsQ0FBQTtRQUNGLE9BQU07SUFDVixDQUFDO0lBRUQsT0FBTTtBQUNWLENBQUMifQ==