Selenium C#中的显式等待不起作用.怎么了?

use*_*802 3 c# selenium automated-tests selenium-chromedriver selenium-webdriver

所以我有明确的等待这个问题.我不想使用Thread.Sleep().这是一个简单的测试,它打开一个页面然后前后移动.加载此页面大约需要2-3秒,我想以动态方式(测试)执行此操作.希望我不是太混乱.我做了很多研究,但没有任何作用,也许我做错了什么.(我正在使用Resharper进行单元测试)

在这里我也有解决方案:

https://www.dropbox.com/s/1k5vjc5czvmdd3u/ConsoleApplication2.rar?dl=0

我正在使用FindElement方法的扩展,所以我相信只需调用此方法并自行等待即可.我在解决方案中有一些解释.如果有人给我一些帮助,我将不胜感激.(抱歉没有那么完美的英语).

using System;
using System.Threading;
using ConsoleApplication2.Extensions;
using NUnit.Framework;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Support.UI;

namespace ConsoleApplication2
{
    class UnitTest1
    {
        private IWebDriver driver = new ChromeDriver();
        [SetUp]
        public void Initialize()
        { 
            driver.Url = "some url";
            Thread.Sleep(3500);
           // driver.Manage().Timeouts().ImplicitlyWait(TimeSpan(20));

        }

       [Test]
        public void CheckBackForward()
        {
            //Go to first page in Online Help
            driver.FindElement(By.XPath("//span/ul/li/span/a")).Click();
            // So if I am commenting this Thread.Sleep
            // it will throw an exception at the extension method at line 13 at "@by"
            // I've also checked this without extension method but still the same problem. It doesn'w wait at all, it will throw this 
            // exception as soon as FindElement method is called.
            // I know that I shouldn't mix explicit waits with implicit ones.
            //Thread.Sleep(1500);
            //Store title
            var title_text = driver.FindElement(By.XPath("//div[@id='shellAreaContent']/div/div[2]/ol/li[3]/span"),60).Text;
            //Check if Back is enabled
            Assert.IsTrue(driver.FindElement(By.XPath("//div[3]/a/span")).Enabled);
            //Go back
            driver.FindElement(By.XPath("//div[3]/a/span")).Click();
            //Check if Forward is enabled
            Assert.IsTrue(driver.FindElement(By.XPath("//div[4]/a/span")).Enabled);
            //Go forward
            driver.FindElement(By.XPath("//div[4]/a/span")).Click();
            //Store title
            var title_text2 = driver.FindElement(By.XPath("//div[@id='shellAreaContent']/div/div[2]/ol/li[3]/span")).Text;
            //Check if you are on the same page
            Assert.AreEqual(title_text2,title_text);
        }



        [TearDown]
        public void EndTest()
        {
            driver.Quit();
        }

    }
}
Run Code Online (Sandbox Code Playgroud)

这是扩展:

using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace ConsoleApplication2.Extensions
{
    public static class Extension
    {
        public static IWebElement FindElement(this IWebDriver driver, By by, int timeoutInSeconds)
        {
            if (timeoutInSeconds <= 0) return driver.FindElement(@by);
            var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(timeoutInSeconds));
            return wait.Until(drv => drv.FindElement(@by));
        }



    }
}
Run Code Online (Sandbox Code Playgroud)

Hap*_*ird 6

我用Selenium编写了6个多月的代码,我和你的问题一样.我创建了这个扩展方法,它每次都适合我.

代码的作用是:在20秒内,它会检查每个500毫秒,无论该元素是否存在于页面上.如果在20秒之后,没有找到,它将抛出异常.这将有助于您进行动态等待.

  public static class SeleniumExtensionMethods {
      public static WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(20));
      public static void SafeClick(this IWebElement webElement) {
          try {
              wait.Until(ExpectedConditions.ElementToBeClickable(webElement)).Click();
          } catch (TargetInvocationException ex) {
              Console.WriteLine(ex.InnerException);
          }

      }
Run Code Online (Sandbox Code Playgroud)

然后替换你的代码:

driver.FindElement(By.XPath("//span/ul/li/span/a")).Click();
Run Code Online (Sandbox Code Playgroud)

有:

IWebElement x = driver.FindElement(By.XPath("//span/ul/li/span/a"));
x.SafeClick();
Run Code Online (Sandbox Code Playgroud)