import { ELEMENT_KEY } from 'webdriver' import { getBrowserObject } from '@wdio/utils' import isElementClickableScript from '../../scripts/isElementClickable.js' /** * * An element is considered to be clickable when the following conditions are met: * * - the element exists * - the element is displayed * - the element is not disabled * - the element is within the viewport * - the element can be scrolled into the viewport * - the element's center is not overlapped with another element * * otherwise return false. * * :::info * * Please note that `isClickable` works only in web browser and in mobile webviews, * it doesn't work in mobile app native context. Also, As opposed to other element * commands WebdriverIO will not wait for the element to exist to execute this command. * * ::: * * :isClickable.js it('should detect if an element is clickable', async () => { const el = await $('#el') let clickable = await el.isClickable(); console.log(clickable); // outputs: true or false // wait for element to be clickable await browser.waitUntil(() => el.isClickable()) }); * * * @alias element.isClickable * @return {Boolean} true if element is clickable * @uses protocol/selectorExecute, protocol/timeoutsAsyncScript * @type state * */ export async function isClickable (this: WebdriverIO.Element) { if (!await this.isDisplayed()) { return false } /** * some Appium platforms don't support the `getContext` method, in that case * we can't determine if we are in a native context or not, so we return undefined */ if (this.isMobile && this.isNativeContext) { throw new Error('Method not supported in mobile native environment. It is unlikely that you need to use this command.') } const browser = getBrowserObject(this) return browser.execute(isElementClickableScript, { [ELEMENT_KEY]: this.elementId, // w3c compatible ELEMENT: this.elementId // jsonwp compatible } as unknown as HTMLElement) }