页面跳转到新窗口并操作新页面的解决方案

场景

由于我测试的应用存在设计态和运行态两个,所以我需要对这两个态都进行验证。但是我的运行态又要依赖于设计态的应用才能进行页面跳转。

问题

我一直卡在这个问题这,以为是我的元素定位不对,但两个态的登录组件都是一样,元素的id及xpath也都是一样的。甚至怀疑是不是内存泄漏。最终都没解决。

控制台一直提示错误

Stacktrace:
GetHandleVerifier [0x00007FF6F4A76CB5+28821]
(No symbol) [0x00007FF6F49E3840]
(No symbol) [0x00007FF6F488578A]
(No symbol) [0x00007FF6F48D91BE]
(No symbol) [0x00007FF6F48D94AC]
(No symbol) [0x00007FF6F4922647]
(No symbol) [0x00007FF6F48FF33F]
(No symbol) [0x00007FF6F491F412]
(No symbol) [0x00007FF6F48FF0A3]
(No symbol) [0x00007FF6F48CA778]
(No symbol) [0x00007FF6F48CB8E1]
GetHandleVerifier [0x00007FF6F4DAFCAD+3408013]
GetHandleVerifier [0x00007FF6F4DC741F+3504127]
GetHandleVerifier [0x00007FF6F4DBB5FD+3455453]
GetHandleVerifier [0x00007FF6F4B3BDBB+835995]
(No symbol) [0x00007FF6F49EEB5F]
(No symbol) [0x00007FF6F49EA814]
(No symbol) [0x00007FF6F49EA9AD]
(No symbol) [0x00007FF6F49DA199]
BaseThreadInitThunk [0x00007FFC9BBA7374+20]
RtlUserThreadStart [0x00007FFC9D17CC91+33]

问题分析

对于以上场景及问题分析,以及一系列网上资料搜索,还有反复询问ai,最终归结为"页面跳转到新窗口并操作新页面"

问题解决

runtime_login_page.py

from pages.base_page import PageObject, PageElement, MultiPageElement
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import logging

# 设置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

class RunTimeLoginPage(PageObject):

    # 运行态账户输入框 username
    run_account = (By.ID, "username")
    # 运行态密码输入框 password
    run_password=(By.ID, "password")
    # 登录按钮
    login_btn = PageElement(xpath="//span[contains(.,'登 录')]")
    # 访问系统按钮
    visit_btn=(By.XPATH, "//span[contains(.,'访问系统')]")
    # 重置密码弹框确定按钮
    sure_btn=PageElement(xpath="//span[contains(.,'确 定')]")

    def __init__(self, driver):
        super().__init__(driver)
        self.driver=driver
        self.vars = {}

    def wait_for_window(self, timeout=2000):
        """等待新窗口出现并返回其句柄"""
        original_handles = set(self.driver.window_handles)
        new_handle = None

        try:
            # 使用显式等待直到窗口句柄数量发生变化
            WebDriverWait(self.driver, timeout / 1000).until(
                lambda d: len(d.window_handles) != len(original_handles)
            )

            # 获取所有窗口句柄,并找出新增的那个
            current_handles = set(self.driver.window_handles)
            new_handle = list(current_handles.difference(original_handles))[0]
            print(f"New window handle detected: {new_handle}")
            # 保存新的窗口句柄到 self.vars
            self.vars["win9871"] = new_handle

        except Exception as e:
            print(f"Timeout waiting for new window: {e}")

        return new_handle

    def navigate_to_runtime_page(self):
        """点击触发打开新窗口的操作"""
        try:
            element=WebDriverWait(self.driver, 20).until(
                EC.visibility_of_element_located(self.visit_btn)
            )
            element.click()
            # 打印当前窗口句柄数量以确认是否有新窗口打开
            print(f"Number of window handles after clicking: {len(self.driver.window_handles)}")
        except  Exception as e:
            logger.error(f"An error occurred during runtime login: {e}", exc_info=True)

    def switch_to_new_window(self, timeout=2000):
        """切换到新开的窗口"""
        new_window_handle = self.wait_for_window(timeout)
        if new_window_handle:
            self.driver.switch_to.window(new_window_handle)
            # 打印当前窗口标题以确认切换成功
            print(f"Switched to new window with title: {self.driver.title}")
        else:
            raise Exception("New window did not open within the specified timeout.")

    def login_runtime(self, username, password):
        logger.info('enter')
        try:            # 确保页面加载完成
            WebDriverWait(self.driver, 20).until(
                lambda driver: driver.execute_script('return document.readyState') == 'complete'
            )
            # 等待账户输入框可见
            account_input = WebDriverWait(self.driver, 20).until(
                EC.visibility_of_element_located(self.run_account)
            )
            logger.info("Account input is visible")
            account_input.send_keys(username)
            WebDriverWait(self.driver, 20).until(
                lambda driver: driver.execute_script('return document.readyState') == 'complete'
            )
            # 等待密码输入框可见
            password_input = WebDriverWait(self.driver, 20).until(
                EC.visibility_of_element_located(self.run_password)
            )
            logger.info("Password input is visible")
            password_input.send_keys(password)
            self.login_btn.click()
        except  Exception as e:
            logger.error(f"An error occurred during runtime login: {e}", exc_info=True)

    def locate_sure_btn(self):
        self.sure_btn.click()

解析:
wait_for_window: 检测新窗口函数
使用显式等待和集合运算来确保新窗口句柄被正确捕获,并立即将其存储在 self.vars 中以便后续引用。
navigate_to_runtime_page:确认新窗口确实打开
确保点击按钮或链接确实触发了新窗口或标签页的打开
switch_to_new_window:处理新窗口/标签页切换
确保在找到新窗口句柄后立即切换到该窗口,并验证页面加载完成

test_login.py

from pages.runtime_login_page import RunTimeLoginPage
from pages.app_page import AppPage
from utils.data_provider import load_test_data
from pages.pub_page import PubPage
import pytest
import time
from .test_app import search_app
test_data = load_test_data('data/test_data.json')

# 登录运行态
@pytest.mark.usefixtures("login")
def test_login_runtime(login):
    runtime_login_page = RunTimeLoginPage(login)
    app_page=AppPage(login)
    # 执行搜索应用操作前打印当前窗口信息
    # print(f"Before search_app: Current window handle is {login.current_window_handle}, title is {login.title}")
    search_app(login,test_data['create_app']['appname'])
    # 执行搜索应用操作后打印当前窗口信息
    print(f"After search_app: Current window handle is {login.current_window_handle}, title is {login.title}")
    # 导航到运行时页面并切换窗口
    runtime_login_page.navigate_to_runtime_page()
    # 切换到新窗口前打印当前窗口信息
    # print(
    #     f"Before switching to new window: Current window handle is {login.current_window_handle}, title is {login.title}")
    runtime_login_page.switch_to_new_window()
    # 切换到新窗口后打印当前窗口信息
    # print(
    #     f"After switching to new window: Current window handle is {login.current_window_handle}, title is {login.title}")
    runtime_login_page.login_runtime(test_data['runtime_valid_user']['username'],test_data['runtime_valid_user']['originPassword'])
    # 登录后再次确认当前窗口信息
    # print(f"After login_runtime: Current window handle is {login.current_window_handle}, title is {login.title}")
    app_page.locate_modify_password(test_data['runtime_valid_user']['password'],test_data['runtime_valid_user']['password'])
    runtime_login_page.locate_sure_btn()
    time.sleep(20)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值