OpenQA.Selenium.NoSuchElementException : 没有这样的元素

OpenQA.Selenium.NoSuchElementException : no such element

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

OpenQA.Selenium.NoSuchElementException : no such element: Unable to locate element: {"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();
    }
}

测试输出:

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

提前谢谢你。

可能需要稍等一下。
尝试添加

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

之前

txtName.SendKeys(Username);

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

  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);
        }
    }