【问题标题】:OpenQA.Selenium.NoSuchElementException : no such elementOpenQA.Selenium.NoSuchElementException :没有这样的元素
【发布时间】:2021-07-29 17:30:38
【问题描述】:

我正在尝试使用 Gherkin 格式通过 Specflow 自动化测试用例,但我一直遇到同样的错误:

OpenQA.Selenium.NoSuchElementException:没有这样的元素:无法找到元素:{"method":"css selector","selector":"*[name="customer_firstname"]"}

文本框的名称是 customer_firstname,我不明白为什么它会显示此错误。

我正在测试的网站是:

http://automationpractice.com/index.php?controller=authentication&back=my-account

小黄瓜文件:

Feature: Register in the website

  Scenario Outline: Register a new user
    Given That I am on the Register page
    And The website will start by entering 
    | email              |
    | gti19001@demo2.com |
    When User enters their credentials
     | firstName | lastName | password     |
     | DEmo      | Demo     | 12345        |
    When The client will enter 
      | Address              | City      | State | Zip   | MobilePhone |
      | Fake adress, 12, efj | Something |     1 | 35242 | +1 5893246 4863 |
    Then Click on the register button

步骤定义文件是:

using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TechTalk.SpecFlow;
using TechTalk.SpecFlow.Assist;
using WebsiteTestingSpecflow.Pages;

namespace WebsiteTestingSpecflow.Steps
{
    [Binding]
    public sealed class RegisterStep
    {

        RegisterPage registerPage = null;

        [Given(@"That I am on the Register page")]
        public void GivenThatIAmOnTheRegisterPage()
        {
            IWebDriver webDriver = new ChromeDriver();
            webDriver.Navigate().GoToUrl("http://automationpractice.com/index.php?controller=authentication&back=my-account");
            registerPage = new RegisterPage(webDriver);
        }

        [Given(@"The website will start by entering")]
        public void GivenTheWebsiteWillStartByEntering(Table table)
        {
            dynamic data = table.CreateDynamicInstance();

            registerPage.Register(data.email.ToString());
 registerPage.VerifyEmail();
        }

        [When(@"User enters their credentials")]
        public void WhenUserEntersTheirCredentials(Table table)
        {
            dynamic data = table.CreateDynamicInstance();

            registerPage.RegisterCredentials(data.firstName.ToString(), data.lastName.ToString(), data.password.ToString());
        }


        [When(@"The client will enter")]
        public void WhenTheClientWillEnter(Table table)
        {
            dynamic data = table.CreateDynamicInstance();

            registerPage.RegisterInformation(data.Address.ToString(), data.City.ToString(), data.State.ToString(), data.Zip.ToString(), data.MobilePhone.ToString());
        }

        [Then(@"Click on the register button")]
        public void ThenClickOnTheRegisterButton()
        {
            registerPage.RegisterBtn();
        }
    }
    }

而实现功能的文件是:

using OpenQA.Selenium;
using System;
using System.Collections.Generic;
using System.Text;

namespace WebsiteTestingSpecflow.Pages
{
    class RegisterPage
    {
        public IWebDriver Webdriver { get; }

        public RegisterPage(IWebDriver webDriver)
        {
            Webdriver = webDriver;
        }


        //UI Elements of Registration
        public IWebElement txtEmailRegister => Webdriver.FindElement(By.Name("email_create"));

        public IWebElement btnRegisterVerify => Webdriver.FindElement(By.CssSelector("#SubmitCreate > span"));

        public IWebElement txtName => Webdriver.FindElement(By.Name("customer_firstname"));

        public IWebElement txtSurname => Webdriver.FindElement(By.Name("customer_lastname"));

        public IWebElement txtPassword => Webdriver.FindElement(By.Name("passwd"));

        public IWebElement txtAddress => Webdriver.FindElement(By.Name("address1"));

        public IWebElement txtCity => Webdriver.FindElement(By.Name("city"));

        public IWebElement txtState => Webdriver.FindElement(By.Name("id_state"));

        public IWebElement txtZIP => Webdriver.FindElement(By.Name("postcode"));

        public IWebElement txtPhone => Webdriver.FindElement(By.Name("phone_mobile"));

        public IWebElement btnRegister => Webdriver.FindElement(By.CssSelector("#submitAccount > span"));


        public void Register(string Email)
        {
            txtEmailRegister.SendKeys(Email);
            
        }

        public void RegisterCredentials(string Username, string Lastname, string password)
        {

            txtName.SendKeys(Username);
            txtSurname.SendKeys(Lastname);
            txtPassword.SendKeys(password);
        }

        public void RegisterInformation(string address, string city, string State, string zip, string phone)
        {
            txtAddress.SendKeys(address);
            txtCity.SendKeys(city);
            txtState.SendKeys(State);
            txtZIP.SendKeys(zip);
            txtPhone.SendKeys(phone);
        }

        public void VerifyEmail() => btnRegisterVerify.Submit();

        public void RegisterBtn() => btnRegister.Submit();
    }
}

测试输出:

有人知道为什么会这样吗?

提前谢谢你。

【问题讨论】:

  • 输入e-mail地址后有什么问题吗?
  • 您能否在edit 您的问题中包含一个具有代表性的 HTML 示例?
  • @GregBurghardt 我在问题中包含了我正在测试的网站的链接。通常应该是在我输入电子邮件并按下创建帐户按钮后,它应该将我重定向到另一个页面,但它没有发生。也许它没有识别按钮?
  • 输入电子邮件后,您永远不会点击按钮转到下一页。您开始链接的页面首先要求创建或登录。您需要先点击创建帐户
  • @JoshAdams 是的,你是对的,我忘了输入方法来输入按钮。我确实修复了它,但我仍然遇到与异常相同的问题。

标签: c# visual-studio selenium specflow gherkin


【解决方案1】:

您可能需要添加一些等待。
尝试添加

wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementIsVisible(By.Name("customer_firstname")));

之前

txtName.SendKeys(Username);

【讨论】:

  • txtName 属性本身正在引发异常,看起来像。
【解决方案2】:

未找到该元素,因为您需要完成当前页面的自动化。

  1. 请注意,您需要点击“创建帐户”按钮。

  2. 很微妙,但是页面淡入。淡入时,元素无法交互,所以需要等待。

您将需要进行以下更改:

  1. 带有电子邮件注册文本字段的页面不是注册页面。它是主页,所以我会为此创建一个页面模型:

    public class HomePage
    {
        private readonly IWebDriver driver;
        private readonly WebDriverWait wait;
    
        private IWebElement EmailInput => driver.FindElement(By.Name("email_create"));
        private IWebElement CreateAccountButton => driver.FindElement(By.Name("SubmitCreate"));
    
        public HomePage(IWebDriver driver)
        {
            this.driver = driver;
            this.wait = new WebDriverWait(driver, TimeSpan.FromSeconds(30));
        }
    
        public RegisterPage Register(string email)
        {
            EmailInput.SendKeys(email);
            CreateAccountButton.Click();
            wait.Until(ExpectedConditions.StalenessOf(By.TagName("body")));
    
            return new RegisterPage(driver);
        }
    }
    
  2. 修改 RegisterPage 以等待某些元素可点击以说明页面在淡入时不可交互:

    public class RegisterPage
    {
        private readonly WebDriverWait wait;
    
        public IWebDriver Webdriver { get; }
    
        // UI elements ....
    
        public RegisterPage(IWebDriver webDriver)
        {
            Webdriver = webDriver;
            wait = new WebDriverWait(webDriver, TimeSpan.FromSeconds(30));
        }
    
        public void RegisterCredentials(string Username, string Lastname, string password)
        {
            // Wait for the page to fade in
            wait.Until(ExpectedConditions.ElementToBeClickable(By.Name("customer_firstname")));
            txtName.SendKeys(Username);
            txtSurname.SendKeys(Lastname);
            txtPassword.SendKeys(password);
        }
    
        public void RegisterInformation(string address, string city, string State, string zip, string phone)
        {
            // Wait for the page to fade in so you are not required
            // to call RegisterCredential before RegisterInformation.
            wait.Until(ExpectedConditions.ElementToBeClickable(By.Name("address1")));
            txtAddress.SendKeys(address);
            txtCity.SendKeys(city);
            txtState.SendKeys(State);
            txtZIP.SendKeys(zip);
            txtPhone.SendKeys(phone);
        }
    }
    

【讨论】:

  • 可能很重要的一点是,这应该是一个不同的页面对象,而不是注册页面。创建帐户或登录页面应该是它自己的,注册是它自己的。
猜你喜欢
  • 2021-09-30
  • 2013-12-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多