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);
未找到元素,因为您需要完成当前页面的自动化。
请注意,您需要单击“创建帐户”按钮。
很微妙,但是页面淡入,在淡入的过程中,元素无法交互,需要稍等。
您需要进行以下更改:
带有电子邮件注册文本字段的页面不是注册页面。这是主页,所以我会为此创建一个页面模型:
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);
}
}
修改 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);
}
}
我正在尝试使用 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);
未找到元素,因为您需要完成当前页面的自动化。
请注意,您需要单击“创建帐户”按钮。
很微妙,但是页面淡入,在淡入的过程中,元素无法交互,需要稍等。
您需要进行以下更改:
带有电子邮件注册文本字段的页面不是注册页面。这是主页,所以我会为此创建一个页面模型:
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); } }
修改 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); } }