Snippets

V findUnblockedElement, findUnblockedButtonByText, and isBlockedByOverlay

Created by V last modified
...
By SECTION_OVERLAY_ANCESTOR_LOCATOR = By.xpath("./ancestor::div[contains(@id, 'section-overlay-')][1]");
...

    private WebElement findUnblockedElement(By by) {
        WebElement element = driver.findElement(by);
        if (isBlockedByOverlay(element)) {
            throw new ElementNotInteractableException(String.format("Element [%s] is blocked by overlay", element.getAttribute("id")));
        } else {
            return element;
        }
    }

    private boolean isBlockedByOverlay(WebElement element) {
        List<WebElement> ancestors = element.findElements(SECTION_OVERLAY_ANCESTOR_LOCATOR);
        WebElement overlayAncestor = ancestors.get(0);
        String overlayClass = overlayAncestor.getAttribute("class");
        return !StringUtils.isBlank(overlayClass);
    }
var /*WebDriver*/ webdriver = require('selenium-webdriver');
var browser = new webdriver.Builder().forBrowser(webdriver.Browser.CHROME).build();
var By = webdriver.By;

/**
 * Find the given element if it is accessible to the user (it's visible, and there's no blocking overlay on top of it).
 * @param by locator to use to find the element
 */
function findUnblockedElement(/*By*/by) {
    let elementPromise = browser.findElement(by);
    return elementPromise.then(element => {
        let ancestorsPromise = element.findElements(By.xpath("./ancestor::div[contains(@id, 'section-overlay-')][1]"));
        return ancestorsPromise.then(function (ancestors) {
            return /*WebElement*/ancestors[0].getAttribute('class').then(className => {
                return new Promise(function (resolve, reject) {
                    if (className !== '') {
                        reject(new Error('Element ' + by + ' is blocked by overlay.'));
                    } else {
                        resolve(element);
                    }
                });
            })
        });
    });
}

findUnblockedButtonByText = function(text) {
    let xpath = "//button[text()='%s']".replace("%s", text);
    return findUnblockedElement(By.xpath(xpath));
};

Comments (1)

  1. V

    The key concept in this scenario was: there were blocking (and not blocking) overlays, with IDs in the form of section-overlay-1, section-overlay-2, section-overlay-3, etc. To determine whether or not a WebElement was blocked (user cannot edit / access the element) by an overlay, I had to find its ancestor div with that section-overlay-* ID. Once I had a reference to that ancestor, I could check if this ancestor had a class attribute. If the class attribute existed, in our case, it was av-block-ui (React Block UI library?), then the current WebElement is blocked.

HTTPS SSH

You can clone a snippet to your computer for local editing. Learn more.