Atata Selenium Web驱动程序无法在Angle App上通过ID查找控件

ian*_*gib 5 c# selenium .net-core angular atata

我一直在努力使用atata作为框架在angular(5)应用程序上建立一个简单的自动化测试,该框架只是包装了硒Web驱动程序以进行测试。为了我的一生,我无法在登录页面上找到我需要的元素。我试过按xpath,css,id和名称查找。都不起作用。请问有人可以帮我了解我做错了什么吗?

我已确保要尝试管理的控件具有适当的ID,并在我检查元素时显示它们。有什么我应该做的事情,以便网络驱动程序访问dom而不访问网站html源(因为它是spa,所以有所区别)?我也尝试过等待10秒钟,然后继续搜索控件。

所有软件包的版本均为最新。

AtataSettings.cs

using Atata;

[assembly: Culture("en-us")]
[assembly: VerifyTitleSettings(Format = "Login")]
Run Code Online (Sandbox Code Playgroud)

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; }
    }
}
Run Code Online (Sandbox Code Playgroud)

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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:

如果我按如下方式使用普通硒设置,我设法使它找到了元素。为什么这项工作可行,但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");
            }
Run Code Online (Sandbox Code Playgroud)

编辑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(&quot;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAASCAYAAABSO15qAAAAAXNSR0IArs4c6QAAAPhJREFUOBHlU70KgzAQPlMhEvoQTg6OPoOjT+JWOnRqkUKHgqWP4OQbOPokTk6OTkVULNSLVc62oJmbIdzd95NcuGjX2/3YVI/Ts+t0WLE2ut5xsQ0O+90F6UxFjAI8qNcEGONia08e6MNONYwCS7EQAizLmtGUDEzTBNd1fxsYhjEBnHPQNG3KKTYV34F8ec/zwHEciOMYyrIE3/ehKAqIoggo9inGXKmFXwbyBkmSQJqmUNe15IRhCG3byphitm1/eUzDM4qR0TTNjEixGdAnSi3keS5vSk2UDKqqgizLqB4YzvassiKhGtZ/jDMtLOnHz7TE+yf8BaDZXA509yeBAAAAAElFTkSuQmCC&quot;); background-repeat: no-repeat; background-attachment: scroll; background-size: 16px 18px; background-position: 98% 50%; cursor: auto;" xpath="1">
Run Code Online (Sandbox Code Playgroud)

Yev*_*ych 5

问题在于错误的控件使用。Atata 具有独特的ControlDefinition功能,可以指定控件元素的基本 XPath。它通过过滤掉错误的元素使元素搜索更加准确。因为TextInput<TOwner>它是[ControlDefinition("input[@type='text' or not(@type)]")]

您的电子邮件元素<input type="email">TextInput<TOwner>. 密码控制也应该如此。

只需将控件类型更改为EmailInput<TOwner>PasswordInput<TOwner>

public class SignInPage : Page<_>
{
    [FindById("email")]
    public EmailInput<_> Email { get; set; }

    [FindById("password")]
    public PasswordInput<_> Password { get; set; }

    //...
}
Run Code Online (Sandbox Code Playgroud)

这是输入控件文档的链接:https : //atata-framework.github.io/components/#inputs

作为一个选项,您还可以将两种控件类型更改为Input<string, TOwner>. 它也可以像Input不那么严格一样工作ControlDefinition

顺便说一句,如果您需要ControlDefinition全局覆盖特定控件的某些默认值:

[assembly: ControlDefinition("input", ComponentTypeName = "text input", TargetType = typeof(TextInput<>))]
Run Code Online (Sandbox Code Playgroud)

或者甚至"*"匹配任何元素。

[assembly: ControlDefinition("*", ComponentTypeName = "text input", TargetType = typeof(TextInput<>))]
Run Code Online (Sandbox Code Playgroud)