在C#中使用Selenium捕获ElementClickInterceptedException

huangapple go评论65阅读模式
英文:

Catch ElementClickInterceptedException in Selenium with C#

问题

我正在尝试在C#中捕获ElementClickInterceptedException,但似乎我做错了什么,因为在调试时,当我遇到该异常时,它不会进入catch代码行。奇怪的是,如果测试正常运行,它在那一点上不会抛出异常,但在调试模式下运行时会...

英文:

I'm trying to catch a ElementClickInterceptedException in C#, but it apppears I'm doing something wrong since it doesn't go to the catch code line when I get that exception while debugging. Strange thing is that if the test runs normally, it doesn't throw the exception at that point, but when it runs in debug mode, it does...在C#中使用Selenium捕获ElementClickInterceptedException

I try catching the exception because Selenium keeps throwing it and I don't know what to do to solve it.

答案1

得分: 0

以下是已翻译的部分:

"Seems like I have been catching the wrong exception all along. Anyway, I'll leave the code that worked for me when I got a TargetInvocationException or ElementClickInterceptedException so anyone facing the same issue can solve it like I did:

看起来我一直捕获了错误的异常。不管怎样,我会留下对我有效的代码,当我遇到TargetInvocationException或ElementClickInterceptedException时,以便任何面临相同问题的人都可以像我一样解决它:"

"public bool clickBtn(IWebElement btnElement)
{
bool result = false;
int attempts = 0;
while (attempts < 10)
{
try
{
waitForClickable(btnElement);
btnElement.Click();
result = true;
break;
}
catch (TargetInvocationException e)
{
}
catch (StaleElementReferenceException e)
{
}
attempts++;
Thread.Sleep(2000);
}
return result;
}"

"I think you can get rid of the second catch and it will work all the same 在C#中使用Selenium捕获ElementClickInterceptedException

我认为你可以删除第二个catch,它会一样起作用 :)"

"Also, I leave the code for the 'waitForClickable' method:

此外,我留下了'waitForClickable'方法的代码:"

"internal void waitForClickable(IWebElement button)
{
try
{
wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementToBeClickable(button));
}
catch (NoSuchElementException e)
{
throw new NoSuchElementException("It wasn't possible to click the element.\n" + e);
}
}"

英文:

Seems like I have been catching the wrong exception all along. Anyway, I'll leave the code that worked for me when I got a TargetInvocationException or ElementClickInterceptedException so anyone facing the same issue can solve it like I did:

public bool clickBtn(IWebElement btnElement)
        {
            bool result = false;
            int attempts = 0;
            while (attempts &lt; 10)
            {
                try
                {
                    waitForClickable(btnElement);
                    btnElement.Click();
                    result = true;
                    break;
                }
                catch (TargetInvocationException e)
                {
                }
                catch (StaleElementReferenceException e)
                {
                }
                attempts++;
                Thread.Sleep(2000);
            }
            return result;
        }

I think you can get rid of the second catch and it will work all the same 在C#中使用Selenium捕获ElementClickInterceptedException

Also, I leave the code for the "waitForClickable" method:

internal void waitForClickable(IWebElement button)
        {
            try
            {
                wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementToBeClickable(button));
            }
            catch (NoSuchElementException e)
            {
                throw new NoSuchElementException(&quot;It wasn&#39;t possible to click the element.\n&quot; + e);
            }
        }

答案2

得分: 0

我为我的框架编写了一个Click()方法,它处理了异常、重试等情况。另外,在其中,你不需要使用Thread.Sleep(),因为WebDriverWait已经负责等待元素可点击。在我的代码中,我用纯粹的超时时间(以秒为单位)替换了循环和计数器。

/// <summary>
/// 点击元素。
/// </summary>
/// <param name="locator">所需元素的 By 定位器。</param>
/// <param name="timeOut">[可选] 等待元素的超时时间(以秒为单位)。默认为10秒。</param>
public void Click(By locator, int timeOut = 10)
{
    DateTime now = DateTime.Now;
    while (DateTime.Now < now.AddSeconds(timeOut))
    {
        try
        {
            new WebDriverWait(Driver, TimeSpan.FromSeconds(timeOut)).Until(ExpectedConditions.ElementToBeClickable(locator)).Click();

            return;
        }
        catch (Exception e) when (e is ElementClickInterceptedException || e is StaleElementReferenceException)
        {
            // 什么都不做,继续循环
        }
    }

    throw new Exception($"无法在{timeOut}秒内单击元素<{locator}>。");
}
英文:

I wrote a Click() method for my framework that takes care of exceptions, retries, etc. Also, you don't need the Thread.Sleep() in there since the WebDriverWait takes care of waiting for the element to be clickable already. In my code, I replaced the loop and counter with a pure timeout in seconds.

/// &lt;summary&gt;
/// Clicks the element.
/// &lt;/summary&gt;
/// &lt;param name=&quot;locator&quot;&gt;The By locator for the desired element.&lt;/param&gt;
/// &lt;param name=&quot;timeOut&quot;&gt;[Optional] How long to wait for the element (in seconds). The default is 10s.&lt;/param&gt;
public void Click(By locator, int timeOut = 10)
{
	DateTime now = DateTime.Now;
	while (DateTime.Now &lt; now.AddSeconds(timeOut))
	{
		try
		{
			new WebDriverWait(Driver, TimeSpan.FromSeconds(timeOut)).Until(ExpectedConditions.ElementToBeClickable(locator)).Click();

			return;
		}
		catch (Exception e) when (e is ElementClickInterceptedException || e is StaleElementReferenceException)
		{
			// do nothing, loop again
		}
	}

	throw new Exception($&quot;Not able to click element &lt;{locator}&gt; within {timeOut}s.&quot;);
}

huangapple
  • 本文由 发表于 2023年2月19日 03:25:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/75495844.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定