首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >不确定如何使用try处理异常,如果找不到元素

不确定如何使用try处理异常,如果找不到元素
EN

Stack Overflow用户
提问于 2020-06-15 12:00:00
回答 1查看 488关注 0票数 0

我试图通过清除输入的用户名字段来处理登录页面上的错误消息。

这是我的代码:

代码语言:javascript
复制
using OpenQA.Selenium;
using System;
using System.Linq.Expressions;
using TestProject.Common.Extensions;
using TestProject.SDK;
using TestProject.SDK.Tests;
using TestProject.SDK.Tests.Helpers;

namespace SecondTest
{
    public class LoginTest : IWebTest
    {
        public object Assert { get; private set; }
        public object TimeUnit { get; private set; }
        public object InvalidInputErrorTxt { get; private set; }
        public bool IWebelement { get; private set; }
        public bool ErrorMsg { get; private set; }

        public ExecutionResult Execute(WebTestHelper helper)
        {
            var driver = helper.Driver;
            var URL = "https://www.office1.bg/login";
            driver.Navigate().GoToUrl(URL);
            driver.Manage().Window.Maximize();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(5);
            driver.FindElementById("CybotCookiebotDialogBodyLevelButtonAccept").Click();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(5);
            //Login
            Pages.LoginPage LoginPage = new Pages.LoginPage(driver);
            LoginPage.PerformLogin("atanas.grudev1@gmail.com", "123456789");
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(5);
            try
            {
                IWebElement Level = driver.FindElementByClassName("corporal-page-list-item");
                if (Level.Displayed)
                {
                    Level.Click();
                    driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(5);
                    driver.FindElementByClassName("corporate-login-button-wrapper").Click();
                    driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(5);
                    return ExecutionResult.Passed;
                }
                else
                {
                    IWebElement ErrorMsg = driver.FindElementByXPath("//*[@id='loginForm']/div/div[1]");
                    if (ErrorMsg.Displayed)
                    {
                        LoginPage.TxtUserName.Clear();
                        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(5);
                        return ExecutionResult.Failed;
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
            return ExecutionResult.Passed;
        }       
            }  
        }

似乎ExecutionResult在开始时需要返回ExecutionResult.Passed/Failed;但是由于我已经尝试捕获,所以我不知道如何获得正确的结果。最终目标是:如果输入了有效的凭据,则应该执行第一个If语句的代码,并获得传递的结果。如果输入的凭据无效,则网站将抛出错误,如果屏幕上存在错误,则应清除用户名字段中的输入并获得失败的结果。

提前谢谢你!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-06-15 14:15:36

几点建议:

  1. 通常,您希望尽可能避免使用try-catch来控制代码流。在本例中,您可以使用driver.FindElements() (注意复数ElementS)并检查空列表,以避免在没有找到任何元素时引发异常。根据医生们的说法,这是一个最佳实践。 不应使用findElement查找不存在的元素,而应使用findElements(By)和断言零长度响应。
  2. ImplicitWait设置超时只需要执行一次。一旦设置,每次搜索元素时都会自动应用该超时。当被召唤的时候它并不会等待..。我想也许你把它和WebDriverWait搞混了
  3. 硒贡献者不推荐使用ImplicitWait。相反,您应该在每次需要等待时使用WebDriverWait
  4. 我建议您研究并使用Page对象模型。如果做得正确,它将为您节省大量的代码重用时间,使您的项目更有组织,并使您的测试代码更加简洁。看起来,您试图在LoginPage.PerformLogin()调用中使用类似Page的内容,但是您的所有driver.FindElement()调用都应该位于适当的页面对象中,并且每个“页面”应该有一个页面对象。

以下是实现前两项建议后的代码。如果你愿意的话,我会让你做3号和4号的。我删除了try-catch,添加了新的if,并删除了除第一个ImplicitWait集之外的所有内容。

代码语言:javascript
复制
using OpenQA.Selenium;
using System;
using System.Collections.Generic;
using System.Linq;
using TestProject.Common.Extensions;
using TestProject.SDK;
using TestProject.SDK.Tests;
using TestProject.SDK.Tests.Helpers;

namespace SecondTest
{
    public class LoginTest : IWebTest
    {
        public object Assert { get; private set; }
        public object TimeUnit { get; private set; }
        public object InvalidInputErrorTxt { get; private set; }
        public bool IWebelement { get; private set; }
        public bool ErrorMsg { get; private set; }

        public ExecutionResult Execute(WebTestHelper helper)
        {
            var driver = helper.Driver;
            var URL = "https://www.office1.bg/login";
            driver.Navigate().GoToUrl(URL);
            driver.Manage().Window.Maximize();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(5);
            driver.FindElementById("CybotCookiebotDialogBodyLevelButtonAccept").Click();

            //Login
            Pages.LoginPage LoginPage = new Pages.LoginPage(driver);
            LoginPage.PerformLogin("atanas.grudev1@gmail.com", "123456789");

            IReadOnlyCollection<IWebElement> level = driver.FindElementsByClassName("corporal-page-list-item");
            if (level.Any() && level.ElementAt(0).Displayed)
            {
                level.ElementAt(0).Click();
                driver.FindElementByClassName("corporate-login-button-wrapper").Click();

                return ExecutionResult.Passed;
            }

            IReadOnlyCollection<IWebElement> errorMsg = driver.FindElementsByXPath("//*[@id='loginForm']/div/div[1]");
            if (errorMsg.Any() && errorMsg.ElementAt(0).Displayed)
            {
                LoginPage.TxtUserName.Clear();
                return ExecutionResult.Failed;
            }

            return ExecutionResult.Passed;
        }
    }
}

关于新代码的几个注意事项,您可能从未见过。

  1. .Any()在LINQto.Count > 0中是等价的。如果列表不是空的,则返回true,否则返回false
  2. .ElementAt()是一个LINQ方法,允许您按索引访问集合的成员。注意:尽管它的名称中有“元素”,但它与WebElement或Selenium无关。

如果你有任何问题,请告诉我。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62387774

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档