5-UI自动化-三大切换,iframe如何定位,窗口新开、alert弹窗如何进行元素定位

5-UI自动化-三大切换,iframe如何定位,窗口新开、alert弹窗如何进行元素定位

上篇介绍4-UI自动化-selenium三大等待操作

web测试过程中有没有遇到以下问题:
1、测试过程中遇到点击后打开了一个新的窗口,这种要如何定位呢?
2、页面嵌套iframe,如何定位元素?
3、有些甚至有alert弹窗,(基本较少,一些银行网站可能会有),如何定位元素?

本篇就来一一介绍

♡ \color{red}{\heartsuit}

新开一个窗口如何定位元素

比如我输入百度url,输入淘宝,点击打开淘宝,然后在淘宝搜索连衣裙,点击淘宝会新开一个窗口,那么这个如何定位呢?

先要了解下窗口句柄的概念。窗口句柄其实可以理解为是窗口的id。
Python的WebDriver模块中,提供了相关方法。
这里截取了current_window_handle()和window_handles()源码,从方法名其实就可以看出,current_window_handle是当前窗口句柄,返回的是一个str类型,window_handles()是返回当前会话的所有窗口,是一个列表。

 	@property
    def current_window_handle(self) -> str:
        """
        Returns the handle of the current window.

        :Usage:
            ::

                driver.current_window_handle
        """
        return self.execute(Command.W3C_GET_CURRENT_WINDOW_HANDLE)['value']

    @property
    def window_handles(self) -> List[str]:
        """
        Returns the handles of all windows within the current session.

        :Usage:
            ::

                driver.window_handles
        """
        return self.execute(Command.W3C_GET_WINDOW_HANDLES)['value']

可以看到,打印出来两个窗口,第一个f75e8ddc-5367-47e2-b458-1a7681ce9e13是百度搜索窗口id,第二个是淘宝页面的窗口id,但是当前的句柄是在百度搜索页面窗口,也就是说,如果要在淘宝页面进行元素定位,需要先将窗口句柄切换到淘宝页面,才能进行元素定位。

在这里插入图片描述
那么如何切换窗口呢?

Python的WebDriver模块提供了switch_to方法,源码如下。注释部分已经为我们提供了几种切换用法,有切换iframe,切换窗口,退回主页面…

switch_to方法

方法 作用
alert = driver.switch_to.alert 切换alter弹窗
driver.switch_to.default_content() 退回主页面
driver.switch_to.frame(‘frame_name’) 通过窗口名切换窗口
driver.switch_to.frame(0) 通过索引切换窗口
driver.switch_to.parent_frame() 退回父级iframe
 	@property
    def switch_to(self) -> SwitchTo:
        """
        :Returns:
            - SwitchTo: an object containing all options to switch focus into

        :Usage:
            ::

                element = driver.switch_to.active_element
                alert = driver.switch_to.alert
                driver.switch_to.default_content()
                driver.switch_to.frame('frame_name')
                driver.switch_to.frame(1)
                driver.switch_to.frame(driver.find_elements_by_tag_name("iframe")[0])
                driver.switch_to.parent_frame()
                driver.switch_to.window('main')
        """
        return self._switch_to

我们用switch_to.window()就可以解决我们的问题,需要将窗口id传进去,但是print(self.driver.current_window_handle) handles = self.driver.window_handles获取到的分别是当前窗口(百度页面),和所有窗口,所有窗口列表中第二个是我们想要元素定位的窗口,那么要怎么传进第二个窗口名呢?不要忘了,它是一个列表,通过列表的取值就可以获取,-1表示获取最后一个窗口,也就是我们新开的窗口。self.driver.switch_to.window(handles[-1])切换到新窗口。

在这里插入图片描述

可以看到成功切换窗口了,那么接下来就回到老知识了,用之前学习过的元素定位就可以了

在这里插入图片描述

最终代码

import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions


class SwitchSample:

    def __init__(self):
        self.driver = webdriver.Firefox()
        # 在打开浏览器驱动等待3s,再去输入url
        self.driver.implicitly_wait(3)
        self.driver.get('http://baidu.com')

    def switch_window(self):
        self.driver.find_element(By.ID, 'kw').send_keys('淘宝')
        # 在点击百度一下前先等待2s
        self.driver.find_element(By.ID, 'su').click()
        # 在输出浏览器的标题前,先等待3s,防止浏览器还未加载完全
        time.sleep(3)
        # 点击淘宝
        self.driver.find_element(By.LINK_TEXT, '淘宝').click()
        print(self.driver.title)
        print("当前的窗口{}".format(self.driver.current_window_handle))
        handles = self.driver.window_handles
        print("当前所有窗口{}".format(handles))
        self.driver.switch_to.window(handles[-1])
        print(f"切换后新的窗口{
      
      self.driver.current_window_handle}")
        time.sleep(2)
        self.driver.find_element(By.ID, 'q').send_keys('连衣裙')
        print(self.driver.current_url, self.driver.title)
        time.sleep(2)
        self.driver.close()
        self.driver.quit()


if __name__ == '__main__':
    ss = SwitchSample()
    ss.switch_window()

在这里插入图片描述

♡ \color{red}{\heartsuit}

iframe定位元素

IFRAME是HTML标签,作用是文档中的文档,或者浮动的框架(FRAME)。iframe元素会创建包含另外一个文档的内联框架(即行内框架)。

如果你用Selenium定位的目标元素在某个iframe里,需要先执行switch_to_frame,否则会找不到元素。

标签是一个内联框架,即用来在当前 HTML 页面中嵌入另一个文档的,且所有主流浏览器都支持iframe标签。

如网易云音乐网站,https://music.163.com/,点击进入网页,F12,查看网页elements,然后点击用户登录。用户登录的id属性为"index-enter-default"。

如果直接通过定位元素driver.find_element(By.ID, "index-enter-default").click(),会出现报错:selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: [id="index-enter-default"]

因为用户登录是在iframe中的
在这里插入图片描述
如果想找一个 iframe 当中的元素,不能直接查找,而是先要进入iframe当中。
我们先要定位iframe元素,进入iframe中,然后再去定位iframe当中的元素。代码实现如下:

import time

from selenium import webdriver
from selenium.webdriver.common.by import By


class SwitchIframe:

    def __init__(self):
        self.driver = webdriver.Firefox()
        self.driver.maximize_window()
        # 在打开浏览器驱动等待3s,再去输入url
        self.driver.implicitly_wait(3)
        self.driver.get('https://music.163.com/')

    def switch_iframe(self):
        # 先定位iframe元素,然后切换进入iframe
        iframe = self.driver.find_element(By.ID, "g_iframe")
        # 等待iframe切换成功
        wait = WebDriverWait(self.driver, 3)
        wait.until(expected_conditions.frame_to_be_available_and_switch_to_it(iframe))
        # 加入显式等待,让代码更智能,增强代码的健壮性
        # self.driver.switch_to.frame(iframe)
        # 找到用户登录,点击
        self.driver.find_element(By.ID, "index-enter-default").click()
        print(self.driver.title)
        time.sleep(2)
        self.driver.close()
        self.driver.quit()


if __name__ == '__main__':
    si = SwitchIframe()
    si.switch_iframe()

在这里插入图片描述
可以用显式等待,等待直到iframe切换成功。在代码中加入这些即可,不知道显式等待的,可以看下我的上篇介绍。

# 等待iframe切换成功
wait = WebDriverWait(self.driver, 3)
wait.until(expected_conditions.frame_to_be_available_and_switch_to_it(iframe))

♡ \color{red}{\heartsuit}

alert弹窗如何定位元素

alter弹窗的切换也是类似的,只是把上面的代码改吧改吧,wait.until(expected_conditions.alert_is_present())目前alter弹窗用的也相对少了,我找不到网站来演示。暂时不介绍了。之后有相关的,再补充。

哈哈哈,终于让我找到了别人写的弹窗:web自动化测试-文件上传与弹框处理

以下摘抄了一些这位网页写的

在页面操作中有时会遇到 JavaScript 所生成的 alert、confirm 以及 prompt 弹框,可以使用 switch_to.alert () 方法定位到。然后使用 text、accept、dismiss、send_keys 等方法进行操作。

  • text:返回 alert、confirm、prompt 中的文字信息。
  • accept ():接受现有警告框,即点击确定。
  • dismiss ():解散现有警告框,即点击取消。
    send_keys (keysToSend):发送文本至警告框。keysToSend: 将文本发送至警告框。

输入一段文本点击比如提交按钮,会弹出确认内容的弹框,这种场景可以使用下面的方式处理:

在这里插入图片描述
通过name属性定位元素
在这里插入图片描述
同理,如果想要自定义输出弹窗内容,定位输入的元素,输入自定义内容即可。
在这里插入图片描述

import time

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.wait import WebDriverWait


class AlertDemo:
    def __init__(self):
        self.driver = webdriver.Firefox()
        self.driver.maximize_window()
        self.driver.implicitly_wait(3)

    def switch_alert(self):
        """Alert弹窗获取文本与确认操作"""
        self.driver.get("http://sahitest.com/demo/alertTest.htm")
        time.sleep(3)
        # 可以自定义弹窗的输出内容
        wait = WebDriverWait(self.driver, 5, 0.5)
        locator = ('xpath', '//input[@name="t1"]')
        wait.until(expected_conditions.visibility_of_element_located(locator)).send_keys('金聪聪,冲冲冲')
        # self.driver.find_element('xpath', '//h2').send_keys("金聪聪,冲冲冲!")
        self.driver.find_element(By.NAME, "b1").click()
        # 添加显示等待,等待弹框的出现
        WebDriverWait(self.driver, 5, 0.5).until(expected_conditions.alert_is_present())
        # 切换到弹框
        alert = self.driver.switch_to.alert
        # 打印弹框的文本
        print(alert.text)
        time.sleep(3)
        # 点击确定,弹窗消失
        alert.accept()
        # 点击取消或者关闭弹框
        # alert.dismiss()


if __name__ == '__main__':
    ad = AlertDemo()
    ad.switch_alert()

下节分享6-UI自动化-鼠标键盘操作

猜你喜欢

转载自blog.csdn.net/weixin_41948075/article/details/128077382
今日推荐