【问题标题】:WebDriverError: element click intercepted: Other element would receive the click - detectionWebDriverError:元素点击被拦截:其他元素将接收点击 - 检测
【发布时间】:2019-09-24 17:36:34
【问题描述】:

我想在尝试点击某个元素之前检测它是否可点击。在我的特定用例中,该元素在处理过程中被其顶部的另一个元素隐藏,完成后,覆盖层被移除并且可以单击该元素。不幸的是,条件elementIsVisible 不考虑一个元素被另一个元素隐藏,方法WebElement.isDisplayed 也不考虑一个元素。

// find an element that is hidden behind some overlay
const hiddenElement = await driver.findElement(By.id('hiddenElement'));

// wait for element returns the "hidden" element
const await visibleElement = driver.wait(webdriver.until.elementIsVisible(hiddenElement));

// "isDisplayed" reports the "hidden" element as visible
const visible = await hiddenElement.isDisplayed();

我可以清楚地使用覆盖元素来检测元素是否被隐藏,但这必须针对每种不同类型的覆盖进行自定义,我实际上正在寻找一种更通用的方法来检测元素是否实际上是 可点击

【问题讨论】:

  • 条件elementToBeClickable怎么样?
  • 有同样的经历。这是因为此刻出现了一些其他的元素。像淡入消息等。解决方案是等到页面稳定。然后执行您的功能。注意 ElementToBeClickable 也可能不起作用
  • @Fenio 我不知道 JavaScript 的 webdriver api 中有任何条件 elementToBeClickable
  • @doberkofler 是的,您寻找 JS 解决方案,但没有这样的解决方案。基本上,此条件检查元素是否为visibleenabled。它不会帮助您解决问题

标签: javascript selenium selenium-webdriver


【解决方案1】:

我确实找到了一个可以按我自己预期工作的解决方案,可以提炼为以下内容:

一个函数isElementClickable负责检查一个元素是否可点击:

function isElementClickable(element) {
    const SCRIPT = `
    const element = arguments[0];

    // is element visible by styles
    const styles = window.getComputedStyle(element);
    if (!(styles.visibility !== 'hidden' && styles.display !== 'none')) {
        return false;
    }

    // is the element behind another element
    const boundingRect = element.getBoundingClientRect();

    // adjust coordinates to get more accurate results
    const left = boundingRect.left + 1;
    const right = boundingRect.right - 1;
    const top = boundingRect.top + 1;
    const bottom = boundingRect.bottom - 1;

    if (document.elementFromPoint(left, top) !== element ||
        document.elementFromPoint(right, top) !== element ||
        document.elementFromPoint(left, bottom) !== element ||
        document.elementFromPoint(right, bottom) !== element) {
        return false;
    }

    return true;
    `;

    return element.getDriver().executeScript(SCRIPT, element);
}

一个可以代替webdriver.until.elementIsVisible作为替换条件的函数'elementIsClickableCondition':

function elementIsClickableCondition(locator) {
    return new webdriver.WebElementCondition('until element is visible', async function (driver) {
        try {
            // find the element(s)
            const elements = await driver.findElements(locator);
            if (elements.length > 1) {
                throw new Error(`elementIsClickableCondition: the locator "${locator.toString()} identifies "${elements.length} instead of 1 element`);
            } else if (elements.length < 1) {
                return null;
            }

            const element = elements[0];

            // basic check if the element is visible using the build-in functionality
            if (!await element.isDisplayed()) {
                return null;
            }

            // really check if the element is visible
            const visible = await isElementClickable(element);

            return visible ? element : null;
        } catch (err) {
            if (err instanceof webdriver.error.StaleElementReferenceError) {
                return null;
            } else {
                throw err;
            }
        }
    });
}

【讨论】:

    猜你喜欢
    • 2021-10-08
    • 2021-08-26
    • 2021-04-17
    • 2021-09-04
    • 1970-01-01
    • 2019-11-08
    • 2022-01-05
    • 2021-10-28
    • 2018-10-26
    相关资源
    最近更新 更多