【问题标题】:using ElementIsVisible in Page Factory Model在页面工厂模型中使用 ElementIsVisible
【发布时间】:2017-07-17 11:17:51
【问题描述】:

我正在尝试在 C# 中使用 Selenium 设置页面工厂模型框架

我已经使用 Selenium 运行了我的测试,但想将我的测试从框架中分离出来。

一些测试要求我在对元素进行任何操作之前等待元素可见。在我的 Selenium 测试的其他版本中,我会做类似

By selector = By.XPath("/html/body/header/div/div[4]/div/div/div[2]/div[1]/form/div[2]/span[2]");
            new WebDriverWait(driver.Instance, TimeSpan.FromSeconds(5)).Until(ExpectedConditions.ElementIsVisible(selector));

但是我无法让 Element Is Visible 工作,因此在我的扩展方法(下面的代码)中使用了等待直到可见。

当我运行我的测试时,即使等待可见 Selenium 也不会在继续之前等待元素出现。当我调试测试时,它在 WaitUntilVisible 步骤中出现 stackOverflow 失败。

当我正常运行测试时,我收到消息没有显示错误,但是它正在显示(我可以在屏幕上看到它)。根据在我的替代框架中运行此测试的经验,我知道这仅仅是因为测试在元素出现之前寻找它。

我已经在我的浏览器工厂类中运行 ImplicitWait。

我是否在页面工厂模型中正确理解并使用了我的等待?

测试我正在运行

[Test]
        public void Framework_Invalid_Location()
        {
            BrowserFactory.InitBrowser("Chrome");
            BrowserFactory.LoadApplication("xxxxxxxxxxxxxx");
            Page.HomePage.SearchForRestaurant("CFYUGHGYHYTDFD");
            Assert.That(Page.HomePage.InvalidPostcode(), Is.EqualTo("Please enter a valid location or postcode"), "message does not show");
            BrowserFactory.CloseAllDrivers();
        }

首页类

        private IWebDriver driver;
        [FindsBy(How = How.CssSelector, Using = "#js-postcode")]
        [CacheLookup]
        private IWebElement PostcodeInput { get; set; }



        [FindsBy(How = How.XPath, Using = "/html/body/header/div/div[4]/div/div/div[2]/div[1]/form/div[2]/span[2]")]
        [CacheLookup]                     
        private IWebElement ErrorMessageInvalidEntry { get; set; }


        public void SearchForRestaurant(string Postcode)
        {
            PostcodeInput.SendKeys(Postcode);
            SearchButton.ClickOnIt("SearchButton");



        public string InvalidPostcode()
        {
            ErrorMessageInvalidEntry.WaitUntilVisible(10);
            return ErrorMessageInvalidEntry.Text;
        }

元素扩展函数我正在等待等待。从 cmets 和建议更新

public static void Wait(this IWebElement element, IWebDriver driver, float TimeOut) {

    WebDriverWait Wait = new WebDriverWait(driver, TimeSpan.FromSeconds(TimeOut));
    return Wait.Until(ExpectedConditions.ElementIsVisible(element));

(元素)的此代码仍然存在一个错误 无法从 OpenQa.Selenium.IWebElement 转换为 open.Qa.Selenium.By

真的觉得我在过去几个月学到的小知识的边缘,所以谢谢大家的帮助。

页面类

namespace KukdFramework.PageObjects
{
    public class Page
    {
        private static T GetPage<T>() where T : new()


        public static HomePage HomePage
        {
            get { return GetPage<HomePage>(); }
        }

浏览器工厂代码

 private static readonly IDictionary<string, IWebDriver> Drivers = new Dictionary<string, IWebDriver>();
        private static IWebDriver driver;

        public static IWebDriver Driver
        {
            get
            {
                if (driver == null)
                    throw new NullReferenceException("The WebDriver browser instance was not initialized. You should first call the method InitBrowser.");
                return driver;
            }
            private set
            {
                driver = value;
            }
        }

        public static void InitBrowser(string browserName)
        {
            switch (browserName)
            {
                case "Firefox":
                    if (driver == null)
                    {
                        driver = new FirefoxDriver();
                        Drivers.Add("Firefox", Driver);
                        BrowserSettings();

                    }
                    break;

                case "IE":
                    if (driver == null)
                    {
                        driver = new InternetExplorerDriver();
                        Drivers.Add("IE", Driver);
                        BrowserSettings();
                    }
                    break;

                case "Chrome":
                    if (driver == null)
                    {
                        driver = new ChromeDriver();
                        Drivers.Add("Chrome", Driver);
                        BrowserSettings();
                    }
                    break;
            }

}

【问题讨论】:

  • 几件事,删除不必要的代码,你已经粘贴了这么多不需要的代码。我猜WaitUntilVisible 没有按预期工作,对吧?怎么了。任何错误或异常,或者它不起作用。请更新问题,而不是在评论中回复。
  • 我已经更新了帖子,我已经包含了所有代码来尝试显示我的框架的结构。因为这对我来说是全新的,所以我不确定是否有一些基本的我做错了导致这个问题。
  • 什么是堆栈跟踪,我不太懂 C#,但似乎 WaitUntilVisible 是自定义函数,而不是 webdriver 提供的。你能用WaitUntilVisible 和堆栈跟踪的实现来更新问题吗?
  • 已经根据 Jordans 的评论和我自己意识到的内容修改了我的代码。但是仍然无法让 WebDriverWait 正常工作。
  • 我不认为是这样,我认为WaitUntilVisible 是一种重载方法。你应该搜索实现,我也没有看到任何堆栈跟踪。

标签: c# .net selenium wait


【解决方案1】:

看起来您的WaitUntilVisible() 扩展方法以递归方式调用自身,没有出路。

这会导致堆栈溢出异常。

您可以将上面的WebDriverWait 调用放在此方法中,然后返回找到的IWebElement,而不是递归调用此方法。

更新(来自 cmets): 您还需要传入WebDriver 实例。在上面的WebDriverWait 行中,您使用driver.Instance

另一种选择是修改扩展方法以要求 WebDriverWait 的实例而不是 float 的等待时间。这样你就不需要自己传入驱动对象了。

【讨论】:

  • 当您发布此内容时,我意识到我的错误。
  • 好的尝试将我的 WebDriver 等待命令放入方法 WebDriverWait wait = new WebDriverWait(TimeSpan.FromSeconds(10));但是我现在收到一个错误,指出 WebDriverWait 不包含带有 1 个参数的构造函数?
  • 更新了我的答案。
  • 好的尝试这样做已经相应地更新了代码,现在出现了2个问题我已经相应地注释了代码。
  • 似乎已经解决了驱动问题,但在将元素传递给函数时仍然存在问题(无法从 .IWebElement 转换为 .By)
【解决方案2】:

我不是 C# 程序员,但是 JAVA 和 C# 是相似的,因此您可能可以转换以下 Java 代码。

WaitUntilVisible 应该是这样的

public static void WaitUntilVisible(WebElement element, int timeOut){
    WebDriverWait wait = new WebDriverWait(driver, timeOut);
    wait.until(ExpectedConditions.visibilityOf(element));
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-23
    相关资源
    最近更新 更多