首页 > 解决方案 > Selenium - Python - 获取用于获取标头值的超时异常消息

问题描述

我正在尝试编写 Pytest 代码,并且在运行测试时,我得到了所有测试的 TimeOut 异常。以下是日志的摘录:

======================================================================== FAILURES ========================================================================
_____________________________________________________ Test_Home.test_check_home_page_header[chrome] ______________________________________________________

self = <Tests.test_HomePage.Test_Home object at 0x000001D3DA012430>

    def test_check_home_page_header(self):
        self.loginPage = LoginPage(self.driver)
>       homepage = self.loginPage.do_login(TestData.U_NAME, TestData.P_WD)

test_HomePage.py:16:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
..\Pages\LoginPage.py:29: in do_login
    self.do_send_keys(self.UNAME, username)
..\Pages\BasePage.py:19: in do_send_keys
    WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(by_locator)).send_keys(text)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <selenium.webdriver.support.wait.WebDriverWait (session="9655edde5d2014440e4ba9fea0b11d55")>
method = <selenium.webdriver.support.expected_conditions.visibility_of_element_located object at 0x000001D3DA038640>, message = ''

    def until(self, method, message=''):
        """Calls the method provided with the driver as an argument until the \
        return value is not False."""
        screen = None
        stacktrace = None

        end_time = time.time() + self._timeout
        while True:
            try:
                value = method(self._driver)
                if value:
                    return value
            except self._ignored_exceptions as exc:
                screen = getattr(exc, 'screen', None)
                stacktrace = getattr(exc, 'stacktrace', None)
            time.sleep(self._poll)
            if time.time() > end_time:
                break
>       raise TimeoutException(message, screen, stacktrace)
E       selenium.common.exceptions.TimeoutException: Message:

..\localsystem\lib\site-packages\selenium\webdriver\support\wait.py:80: TimeoutException
______________________________________________________ Test_Home.test_check_home_page_header[edge] _______________________________________________________

self = <Tests.test_HomePage.Test_Home object at 0x000001D3DA0A7D90>

    def test_check_home_page_header(self):
        self.loginPage = LoginPage(self.driver)
>       homepage = self.loginPage.do_login(TestData.U_NAME, TestData.P_WD)

test_HomePage.py:16:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
..\Pages\LoginPage.py:29: in do_login
    self.do_send_keys(self.UNAME, username)
..\Pages\BasePage.py:19: in do_send_keys
    WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(by_locator)).send_keys(text)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <selenium.webdriver.support.wait.WebDriverWait (session="a940b700b12b4aa923d01faaa45913cc")>
method = <selenium.webdriver.support.expected_conditions.visibility_of_element_located object at 0x000001D3DA0A7DC0>, message = ''

    def until(self, method, message=''):
        """Calls the method provided with the driver as an argument until the \
        return value is not False."""
        screen = None
        stacktrace = None

        end_time = time.time() + self._timeout
        while True:
            try:
                value = method(self._driver)
                if value:
                    return value
            except self._ignored_exceptions as exc:
                screen = getattr(exc, 'screen', None)
                stacktrace = getattr(exc, 'stacktrace', None)
            time.sleep(self._poll)
            if time.time() > end_time:
                break
>       raise TimeoutException(message, screen, stacktrace)
E       selenium.common.exceptions.TimeoutException: Message:

我已经在配置类中定义了标头值并从那里读取。我正在尝试实现POM,所以登录页面执行后,它直接切换到HomePage。下面是代码的实现(BaseClass.py):

超时定义:

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


class BasePage():

    def __init__(self, driver):
        self.driver = driver

    def is_visible(self, by_locator):
        element = WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(by_locator))
        return bool(element)

登录页面(LoginPage.py)

import time
from Pages.BasePage import BasePage
from Pages.HomePage import HomePage
from selenium.webdriver.common.by import By
from Config.config import TestData

class LoginPage(BasePage):

   UNAME = (By.ID, "UserName")
   PWD = (By.ID, "User_Password")
   LOGIN_BTN = (By.XPATH, '//button[@type="submit"]')
   EULA_BTN = (By.XPATH, "//button[normalize-space()='I Agree']")
   
   def __init__(self, driver):
      super().__init__(driver)
      self.driver.get(TestData.BASE_URL)

"""BELOW ARE PAGE ACTIONS FOR LOGIN PAGE"""

   def get_login_page_title(self, title):
      return self.get_title(title)

"""For logging in into the account"""
   def do_login(self, username, password):
      self.do_send_keys(self.UNAME, username)
      self.do_send_keys(self.PWD, password)
      self.do_click(self.LOGIN_BTN)
      self.do_click(self.EULA_BTN)

      return HomePage(self.driver)

登录页面测试文件 (test_LoginPage.py)

import pytest
from Config.config import TestData
from Tests.test_Base import BaseTest
from Pages.LoginPage import LoginPagecode

class Test_Login(BaseTest):
    
  def test_login_page_title(self):
      self.loginPage = LoginPage(self.driver)
      title = self.loginPage.get_title(TestData.LOGIN_PAGE_TITLE)
      assert title == TestData.LOGIN_PAGE_TITLE

  def test_login(self):
      self.loginPage = LoginPage(self.driver)
      self.loginPage.do_login(TestData.U_NAME, TestData.P_WD)

主页对象定义 (HomePage.py)

import time
from Pages.BasePage import BasePage
from selenium.webdriver.common.by import By
from Config.config import TestData

class HomePage(BasePage):

    HEADER = (By.ID, "SiteTitle")

    def __init__(self, driver):
        super().__init__(driver)

    """For checking if the Page Header text matches"""
    def get_header_value(self):
        if self.is_visible(self.HEADER):
            return self.get_element_text(self.HEADER)

以下是主页(test_HomePage.py)的相应测试类:

import pytest
from Config.config import TestData
from Tests.test_Base import BaseTest
from Pages.LoginPage import LoginPage

class Test_Home(BaseTest):

    def test_check_home_page_header(self):
        self.loginPage = LoginPage(self.driver)
        homepage = self.loginPage.do_login(TestData.U_NAME, TestData.P_WD)
        home_header = homepage.get_header_value()
        assert home_header == TestData.HOME_PAGE_HEADER

很长时间以来,我一直坚持这一点,因为我已经为我的其他测试项目实现了类似的代码模式,并且它按预期工作。如果需要更多详细信息,请告诉我。TIA。

标签: pythonpython-3.xseleniumautomated-testspytest

解决方案


我不是 100% 确定,但我认为问题出在这个函数上:

class Test_Home(BaseTest):
    def test_check_home_page_header(self):
        self.loginPage = LoginPage(self.driver)
        homepage = self.loginPage.do_login(TestData.U_NAME, TestData.P_WD)  # Doing login after logged in?
        home_header = homepage.get_header_value()
        assert home_header == TestData.HOME_PAGE_HEADER

您正在尝试在主页上输入登录名和密码,而不是在登录页面上。您之前在这里登录过:

import pytest
from Config.config import TestData
from Tests.test_Base import BaseTest
from Pages.LoginPage import LoginPagecode

class Test_Login(BaseTest):
    
  def test_login_page_title(self):
      self.loginPage = LoginPage(self.driver)
      title = self.loginPage.get_title(TestData.LOGIN_PAGE_TITLE)
      assert title == TestData.LOGIN_PAGE_TITLE

  def test_login(self):
      self.loginPage = LoginPage(self.driver)
      self.loginPage.do_login(TestData.U_NAME, TestData.P_WD)

为什么我这么认为?由于来自堆栈跟踪的这些信息:

\Pages\LoginPage.py:29: in do_login
    self.do_send_keys(self.UNAME, username)
..\Pages\BasePage.py:19: in do_send_keys
    WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(by_locator)).send_keys(text)

您正在尝试输入用户名,但未找到该字段。

因此,请尝试以下操作:

  1. 删除homepage = self.loginPage.do_login(TestData.U_NAME, TestData.P_WD)test_check_home_page_header重新运行测试
  2. 如果您在每次测试前登录,请清除 cookie。

推荐阅读