如果元素不可见,则继续方法

时间:2020-06-24 19:42:58

标签: c# selenium element

我正在用C#/ Selenium测试UI,并且有一个数据输入部分,然后是一个结果窗口。返回结果或没有结果。我正在测试这两种情况

我为此测试创建了一种方法,如下所示。可以用来测试是/否方案是否存在元素...

    public bool HasResults()
    {

            IList<IWebElement> yesResultElement = _driver.FindElements(yesResults);

            if (yesResultElement.Count > 0)
            {
                return true;
            }


            IList<IWebElement> noResultElement = _driver.FindElements(noResults);
        
            if (noResultElement.Count > 0)
            {
                return false;
            }

        throw new Exception("Could not determine if there were results");

    }

问题是,当我测试'noResultElement'时,此方法挂断并超时,因为找不到'yesResultElement'。

我尝试在第一个IF语句周围添加try / catch

    public bool HasResults()
    {
        try
        {

            IList<IWebElement> yesResultElement = _driver.FindElements(yesResults);

            if (yesResultElement.Count > 0)
            {
                return true;
            }
        }
        catch
        {
            Console.WriteLine("element does not exist");
        }

        IList<IWebElement> noResultElement = _driver.FindElements(noResults);
        
        if (noResultElement.Count > 0){
            return false;
        }

        throw new Exception("Could not determine if there were results");

    }

这可以解决问题,但也可以将20秒的测试转换为> 1分钟(由于在测试文件中指定了隐式等待)

除了将其分为2种方法外,还有没有更好的方法来处理此问题?如果没有yesResultElement,请忽略该IF语句,然后移到下一个我想要的语句。

测试看起来像这样

[TestMethod]

    public void NoRecordsFoundTest()
    {
        // Tests whether no records are found when that is the expected outcome
        var searchPage = new SearchPage(driver);
        var firstTest = testData.First();
        searchPage.EnterSearchInfo(firstTest);
        var result = searchPage.HasResults();
        try
        {
            result.Should().BeFalse();
            log.Debug("The No Records Found Test Passed");
        }
        catch (AssertFailedException ex)
        {
            log.Debug("The No Records Found Test Failed",ex);
            Assert.Fail();
        }
    }


    [TestMethod]

    public void RecordsFoundTest()
    {

        // Tests whether records are found when that is the expected outcome

        var searchPage = new SearchPage(driver);
        var firstTest = testData.Skip(1).First();
        searchPage.EnterSearchInfo(firstTest);
        var result = searchPage.HasResults();
        try
        {
            result.Should().BeTrue();
            log.Debug("The Records Found Test Passed");
        }
        catch (AssertFailedException ex)
        {
            log.Debug("The Records Found Test Failed", ex);
            Assert.Fail();
        }
    }

不确定其相关性,但测试数据已从JSON文件加载并传递到EnterSearchInfo()方法中。

此外,即使返回结果,UI也会出现一个小故障,一瞬间出现noResultElement,然后消失。

1 个答案:

答案 0 :(得分:1)

您可以将隐式等待超时临时设置为一个较小的值,重复尝试查找您的元素,等待直到找到至少一个组(使用OpenQA.Selenium.Support.UI.WebDriverWait),然后根据所使用的组返回布尔值。找到。

这样的扩展方法可能会有所帮助:

public static class WebDriverExtensions
{
    /// <summary>
    /// Executes the specified `action` with `ImplicitWait` set to the specified `timeout`.
    /// </summary>
    /// <typeparam name="T">The action return type.</typeparam>
    /// <param name="b">The WebDriver instance.</param>
    /// <param name="timeout">
    /// The duration that WebDriver should implicitly wait until it gives up on trying to
    /// find an element.
    /// </param>
    /// <param name="action">
    /// The action to execute with the special ImplicitWait setting.
    /// </param>
    /// <returns>The action result.</returns>
    public static T WithImplicitWait<T>(this ChromeDriver b, TimeSpan timeout, Func<T> action)
    {
        ITimeouts timeouts = b.Manage().Timeouts();
        TimeSpan oldImplicitWait = timeouts.ImplicitWait;
        try
        {
            timeouts.ImplicitWait = timeout;
            return action();
        }
        finally
        {
            timeouts.ImplicitWait = oldImplicitWait;
        }
    }
}

然后您将像这样使用它:

public bool HasResults()
{
    var wait = new WebDriverWait(_driver, TimeSpan.FromSeconds(10))
    {
        Message = "Could not find neither 'yes' nor 'no' results."
    };
    var implicitTimeout = TimeSpan.FromMilliseconds(200);
    string found =_driver.WithImplicitWait(implicitTimeout, () => wait.Until(b =>
    {
        IList<IWebElement> yesResultElement = _driver.FindElements(yesResults);
        IList<IWebElement> noResultElement = _driver.FindElements(noResults);
        if (yesResultElement.Count == 0 && noResultElement.Count == 0)
        {
            return null;
        }

        if (yesResultElement.Count > 0 && noResultElement.Count > 0)
        {
            return "both";
        }

        return yesResultElement.Count > 0 ? "yes" : "no";
    }));
    bool result = found switch
    {
        "yes" => true,
        "no" => false,
        _ => throw new Exception("Could not determine if there were results")
    };
    return result;
}

WebDriverWait.Until将重复调用您的回调,直到它返回非null值为止,因此当找不到两个组时,我们将返回null。 (在这种情况下)它将在10秒后放弃,并失败并显示指定的错误消息。

相关问题