Atata selenium 网络驱动程序无法在 angular 应用程序上按 ID 找到控件
Atata selenium web driver can't find controls by id on angular app
我一直在努力在 angular (5) 应用程序上设置一个简单的自动化测试,该应用程序使用 atata 作为框架,它简单地包装了 selenium 网络驱动程序来进行测试。对于我的生活,我无法在登录页面中找到我需要的元素。我试过通过 xpath、css、id 和名称查找。 None 其中工作。如果我做错了什么,请有人帮助我理解吗?
我已确保我尝试管理的控件的 ID 已到位,并且当我检查元素时它们会显示。有什么我应该做的,以便 webdriver 访问 dom 而不是网站 html 源(因为它是一个水疗中心而有所不同)?我也试过等10秒再继续搜索控件。
所有包的版本都是最新的。
AtataSettings.cs
using Atata;
[assembly: Culture("en-us")]
[assembly: VerifyTitleSettings(Format = "Login")]
SignInPage.cs
using Atata;
namespace PortalTests2
{
using _ = SignInPage;
[Url("auth/login")]
[VerifyTitle]
public class SignInPage : Page<_>
{
[FindById("email")]
public TextInput<_> Email { get; set; }
[FindById("password")]
public TextInput<_> Password { get; set; }
[FindById("login_button")]
public Button<_> SignIn { get; set; }
[FindById]
public Select<_> selectedClientId { get; set; }
[FindById("continue_button")]
public Button<_> ContinueButton { get; set; }
}
}
SignInTests.cs
using Atata;
using NUnit.Framework;
namespace PortalTests2
{
[TestFixture]
public class SignInTests
{
[SetUp]
public void SetUp()
{
AtataContext.Configure().
UseChrome().
WithFixOfCommandExecutionDelay().
WithLocalDriverPath().
UseBaseUrl($"http://localhost:4300/").
UseNUnitTestName().
AddNUnitTestContextLogging().
AddScreenshotFileSaving().
LogNUnitError().
TakeScreenshotOnNUnitError().
Build();
}
[TearDown]
public void TearDown()
{
AtataContext.Current?.CleanUp();
}
[Test]
public void SignIn()
{
Go.To<SignInPage>().
Email.Set("root").
Password.Set("r00t").
SignIn.Click();
}
}
}
编辑:
如果我使用普通的硒设置,我设法让它找到元素,如下所示。为什么这行得通但 Atata 的包装行不通?
using (var driver = new ChromeDriver(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)))
{
driver.Navigate().GoToUrl(@"http://localhost:4300/");
var link = driver.FindElement(By.Id("email"));
link.SendKeys("hello");
}
编辑 2:
我发现有人有类似的问题,但它被限制在文件输入字段中。有人可以确认我正在使用的设置是否存在挥之不去的错误吗?
https://github.com/atata-framework/atata/issues/188
编辑 3:
Html 电子邮件字段输入控件的片段:
<input autocomplete="off" class="form-control ng-pristine ng-valid ng-touched" id="email" name="email" placeholder="Email address" type="email" ng-reflect-name="email" ng-reflect-is-disabled="false" style="background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAASCAYAAABSO15qAAAAAXNSR0IArs4c6QAAAPhJREFUOBHlU70KgzAQPlMhEvoQTg6OPoOjT+JWOnRqkUKHgqWP4OQbOPokTk6OTkVULNSLVc62oJmbIdzd95NcuGjX2/3YVI/Ts+t0WLE2ut5xsQ0O+90F6UxFjAI8qNcEGONia08e6MNONYwCS7EQAizLmtGUDEzTBNd1fxsYhjEBnHPQNG3KKTYV34F8ec/zwHEciOMYyrIE3/ehKAqIoggo9inGXKmFXwbyBkmSQJqmUNe15IRhCG3byphitm1/eUzDM4qR0TTNjEixGdAnSi3keS5vSk2UDKqqgizLqB4YzvassiKhGtZ/jDMtLOnHz7TE+yf8BaDZXA509yeBAAAAAElFTkSuQmCC"); background-repeat: no-repeat; background-attachment: scroll; background-size: 16px 18px; background-position: 98% 50%; cursor: auto;" xpath="1">
问题出在错误的控件使用上。 Atata 具有独特的 ControlDefinition
功能,它指定控件元素的基本 XPath。它通过过滤掉错误的元素使元素搜索更加准确。 TextInput<TOwner>
是 [ControlDefinition("input[@type='text' or not(@type)]")]
.
您的电子邮件元素是 <input type="email">
,它与 TextInput<TOwner>
的基本 XPath 不匹配。密码控制也应该如此。
只需将控件类型更改为 EmailInput<TOwner>
和 PasswordInput<TOwner>
:
public class SignInPage : Page<_>
{
[FindById("email")]
public EmailInput<_> Email { get; set; }
[FindById("password")]
public PasswordInput<_> Password { get; set; }
//...
}
这里是 link 输入控件文档:https://atata-framework.github.io/components/#inputs
作为一个选项,您还可以将两种控件类型都更改为 Input<string, TOwner>
。它也可以工作,因为 Input
不那么严格 ControlDefinition
.
顺便说一下,如果您需要为全局特定控件覆盖一些默认值 ControlDefinition
:
[assembly: ControlDefinition("input", ComponentTypeName = "text input", TargetType = typeof(TextInput<>))]
或偶数 "*"
以匹配任何元素。
[assembly: ControlDefinition("*", ComponentTypeName = "text input", TargetType = typeof(TextInput<>))]
我一直在努力在 angular (5) 应用程序上设置一个简单的自动化测试,该应用程序使用 atata 作为框架,它简单地包装了 selenium 网络驱动程序来进行测试。对于我的生活,我无法在登录页面中找到我需要的元素。我试过通过 xpath、css、id 和名称查找。 None 其中工作。如果我做错了什么,请有人帮助我理解吗?
我已确保我尝试管理的控件的 ID 已到位,并且当我检查元素时它们会显示。有什么我应该做的,以便 webdriver 访问 dom 而不是网站 html 源(因为它是一个水疗中心而有所不同)?我也试过等10秒再继续搜索控件。
所有包的版本都是最新的。
AtataSettings.cs
using Atata;
[assembly: Culture("en-us")]
[assembly: VerifyTitleSettings(Format = "Login")]
SignInPage.cs
using Atata;
namespace PortalTests2
{
using _ = SignInPage;
[Url("auth/login")]
[VerifyTitle]
public class SignInPage : Page<_>
{
[FindById("email")]
public TextInput<_> Email { get; set; }
[FindById("password")]
public TextInput<_> Password { get; set; }
[FindById("login_button")]
public Button<_> SignIn { get; set; }
[FindById]
public Select<_> selectedClientId { get; set; }
[FindById("continue_button")]
public Button<_> ContinueButton { get; set; }
}
}
SignInTests.cs
using Atata;
using NUnit.Framework;
namespace PortalTests2
{
[TestFixture]
public class SignInTests
{
[SetUp]
public void SetUp()
{
AtataContext.Configure().
UseChrome().
WithFixOfCommandExecutionDelay().
WithLocalDriverPath().
UseBaseUrl($"http://localhost:4300/").
UseNUnitTestName().
AddNUnitTestContextLogging().
AddScreenshotFileSaving().
LogNUnitError().
TakeScreenshotOnNUnitError().
Build();
}
[TearDown]
public void TearDown()
{
AtataContext.Current?.CleanUp();
}
[Test]
public void SignIn()
{
Go.To<SignInPage>().
Email.Set("root").
Password.Set("r00t").
SignIn.Click();
}
}
}
编辑:
如果我使用普通的硒设置,我设法让它找到元素,如下所示。为什么这行得通但 Atata 的包装行不通?
using (var driver = new ChromeDriver(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)))
{
driver.Navigate().GoToUrl(@"http://localhost:4300/");
var link = driver.FindElement(By.Id("email"));
link.SendKeys("hello");
}
编辑 2:
我发现有人有类似的问题,但它被限制在文件输入字段中。有人可以确认我正在使用的设置是否存在挥之不去的错误吗?
https://github.com/atata-framework/atata/issues/188
编辑 3:
Html 电子邮件字段输入控件的片段:
<input autocomplete="off" class="form-control ng-pristine ng-valid ng-touched" id="email" name="email" placeholder="Email address" type="email" ng-reflect-name="email" ng-reflect-is-disabled="false" style="background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAASCAYAAABSO15qAAAAAXNSR0IArs4c6QAAAPhJREFUOBHlU70KgzAQPlMhEvoQTg6OPoOjT+JWOnRqkUKHgqWP4OQbOPokTk6OTkVULNSLVc62oJmbIdzd95NcuGjX2/3YVI/Ts+t0WLE2ut5xsQ0O+90F6UxFjAI8qNcEGONia08e6MNONYwCS7EQAizLmtGUDEzTBNd1fxsYhjEBnHPQNG3KKTYV34F8ec/zwHEciOMYyrIE3/ehKAqIoggo9inGXKmFXwbyBkmSQJqmUNe15IRhCG3byphitm1/eUzDM4qR0TTNjEixGdAnSi3keS5vSk2UDKqqgizLqB4YzvassiKhGtZ/jDMtLOnHz7TE+yf8BaDZXA509yeBAAAAAElFTkSuQmCC"); background-repeat: no-repeat; background-attachment: scroll; background-size: 16px 18px; background-position: 98% 50%; cursor: auto;" xpath="1">
问题出在错误的控件使用上。 Atata 具有独特的 ControlDefinition
功能,它指定控件元素的基本 XPath。它通过过滤掉错误的元素使元素搜索更加准确。 TextInput<TOwner>
是 [ControlDefinition("input[@type='text' or not(@type)]")]
.
您的电子邮件元素是 <input type="email">
,它与 TextInput<TOwner>
的基本 XPath 不匹配。密码控制也应该如此。
只需将控件类型更改为 EmailInput<TOwner>
和 PasswordInput<TOwner>
:
public class SignInPage : Page<_>
{
[FindById("email")]
public EmailInput<_> Email { get; set; }
[FindById("password")]
public PasswordInput<_> Password { get; set; }
//...
}
这里是 link 输入控件文档:https://atata-framework.github.io/components/#inputs
作为一个选项,您还可以将两种控件类型都更改为 Input<string, TOwner>
。它也可以工作,因为 Input
不那么严格 ControlDefinition
.
顺便说一下,如果您需要为全局特定控件覆盖一些默认值 ControlDefinition
:
[assembly: ControlDefinition("input", ComponentTypeName = "text input", TargetType = typeof(TextInput<>))]
或偶数 "*"
以匹配任何元素。
[assembly: ControlDefinition("*", ComponentTypeName = "text input", TargetType = typeof(TextInput<>))]