Title image of A trick to fix Selenium “Element is not clickable at point” (C#)

A trick to fix Selenium “Element is not clickable at point” (C#)

9 December 2023

·
C#

Grass is green, Water is wet and front-end tests fail.

Selenium is an amazing thing. It lets us automate the browser and test our applications from the user's perspective. The entire stack can be tested in a single test and we can be sure everything is working as it should before we deploy to production. Amazing stuff.

Unfortunately, Selenium also makes me want to claw my eyeballs out. It’s not its fault. Automated front-end testing is inherently flaky. JavaScript, loading times and animations cause havoc for tests. Loads of test waits are added to make sure elements are loaded and our tests pass. Then we get angry with how long the tests are taking so we rip them all out. Then we have a production outage so we start the tests all over again.

Element not clickable

Adding waits is all standard Selenium stuff but an annoying message I’ve been getting recently is this:

“Element is not clickable at point”

The problem seems to occur when the element is just off the screen. Selenium seems unable to move to the element. I’ve tried all the solutions suggested in other articles without any luck.

The fix

To fix the issue I had to explicitly scroll the browser to the element being clicked. The code takes the size of the window and tries to align the element to the centre of the window. I did this for all clicks in the tests with a common method. It seems completely overkill to do this but hey it did fix the issue 🤣

Here’s the code:

// Driver defined above as a private variable

public void ClickByXPath(string xpath)
{
    ScrollToElement(xpath);

    Driver.FindElement(By.XPath(xpath))
        .Click();
}

// This might seem over the top but we were having alot of problems with Selenium not being able to click elements.
// So this method manually scrolls the window so the element is as center as possible in the window.
public void ScrollToElement(string xpath)
{
    int windowTop;

    try
    {
        windowTop = (int)(long)((IJavaScriptExecutor)Driver).ExecuteScript("return window.pageYOffset;");
    }
    catch
    {
        windowTop = (int)(double)((IJavaScriptExecutor)Driver).ExecuteScript("return window.pageYOffset;");
    }

    var windowHeight = (int)(long)((IJavaScriptExecutor)Driver).ExecuteScript("return window.innerHeight;");

    var targetElementY = Driver.FindElement(By.XPath(xpath)).Location.Y;

    var scrollAmount = 0;

    // Is target above or below current window?
    if (targetElementY > windowTop + windowHeight || targetElementY < windowTop)
    {
        // Try to scroll element to center of window
        scrollAmount = targetElementY - (windowTop + windowHeight / 2);
    }

    Actions actions = new Actions(Driver);
    actions.ScrollByAmount(0, scrollAmount);
    actions.Perform();
}

It’s a pretty nifty bit of code. The only way to get the window size information is by running Javascript which is what the IJavaScriptExecutor is doing. It then uses that info to work out if the element is above or below the window and scrolls the window appropriately.

Hope it helps if you’re also stuck on this error 🙂