Selenium:打开扩展的弹出窗口

2023-12-04

我正在尝试使用 Selenium 为我的扩展编写 E2E 测试。对于我的测试,我需要打开扩展程序的弹出页面 - 就好像用户单击扩展程序的徽标(位于浏览器的右下角)一样。

我已经成功地使用扩展程序初始化了 ChromeDriver,方法是:

ChromeOptions options = new ChromeOptions();
options.addExtensions(new File("...\\dist.crx"));

这样,浏览器(网络驱动程序)就会根据需要打开并安装。但问题是,我需要以某种方式打开弹出页面。

所以我想到了一个很好的解决方案,不幸的是没有奏效: 我设置了键盘快捷键来打开扩展程序(使用 Google 的命令接口)。问题是 - 它仅有效manually.

手动选择我选择的快捷方式(Ctrl + Shift + Y)opens根据需要扩展。但是当使用 Selenium 将这些密钥发送到浏览器时,什么都没发生*:

Actions actions = new Actions(webDriver);
actions.sendKeys(Keys.chord(Keys.CONTROL, Keys.SHIFT, "Y")).perform();

因此,由于此方法不起作用,我使用 Java 的 Robot 来单击扩展程序的图标,并为其提供 x,y 偏移坐标。这个解决方案是有效的,但它非常丑陋而且不好,因为它无法在不同的屏幕上正确点击。我正在尝试找到一个可以在所有屏幕尺寸上运行的全局解决方案。

提前致谢。

*当我以这种方式发送密钥时,其他操作对我来说效果很好(例如 Control + A 来标记所有) - 所以我猜测问题不在于我发送密钥的方式。

澄清:我想测试相互作用在我的弹出页面(和后台脚本)与 DOM 本身(内容脚本)之间。这意味着我需要有both打开弹出页面,对其执行一些操作,然后对网页的“真实”DOM 进行断言。因此,仅全屏打开弹出页面并不能让我编写所有我想要的 E2E 测试。


我解决这个问题的方法是直接打开页面。

换句话说,Chrome 扩展程序中的所有页面都只是内置于包中的 HTML 页面。因此,您可以使用特制的 URL 直接打开它们。

第一步是找出您的包裹 ID。它是一个唯一的 32 个字符的字符串。该值源自用于对包进行签名的密钥,因此它应该相当一致。找到该值的最快方法是:

  1. 打开已安装扩展程序的 Chrome
  2. 转到扩展列表(菜单 > 更多工具 > 扩展)
  3. 确保选中顶部的“开发者模式”复选框
  4. 在列表中找到您的分机,将会有一个名为“ID:”的条目
  5. 复制这个值

例如,云端硬盘的应用程序启动器是“ID: lmjegmlicamnimmfhcmpkclmigmmcbeh"

知道该值意味着您现在可以访问包中的任何页面。

String EXTENSION_PROTOCOL = "chrome-extension";
String EXTENSION_ID = "lmjegmlicamnimmfhcmpkclmigmmcbeh";
indexPage = EXTENSION_PROTOCOL + "://" + EXTENSION_ID + "/index.html";
optionsPage = EXTENSION_PROTOCOL + "://" + EXTENSION_ID + "/options/options.html";

driver.get(indexPage);

这样做有一些缺点:

  • 它不测试按钮本身
  • 页面始终全屏呈现,因此您可能会遇到一些布局问题

如果您可以解决这些问题,那么您至少可以测试 Chrome 扩展程序的大部分功能。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Selenium:打开扩展的弹出窗口 的相关文章

随机推荐

  • 动态打开Javascript中定义的radwindow

    客观的 从服务器端 我需要在 IF 条件下自动打开一个 radwindow 在 aspx 页面的 JavaScript 中定义 使用的代码 在 aspx 页面中 我将 radwindow 定义为
  • 在 dplyr 中使用动态位置数创建滞后/超前变量

    我正在寻找一种方法来生成从具有动态位置数的滞后列派生的列 参数n 这意味着这个新列应该作为参数n存储在另一列中的值 参见lag文档功能 样本数据 set seed 42 df lt as tibble data frame id c rep
  • ARM 存储寄存器

    在ARM中有一个Banked Register的概念 在阅读许多问题及其答案以及有关什么的各种其他资源时Banked意思是这里 然后我得到了这个定义 登记银行业务是指在同一地址提供登记册的多份副本 并非所有寄存器都能立即看到 但我在这里的疑
  • Java Selenium - ExpectedCopnditions 存在通过但可见性失败

    我不明白 我已经寻找答案两天了 但我找不到解决这个问题的单一解决方案 代码如下所示 在 try catch 块内 Presence new WebDriverWait Driver custTimeout Presence until Ex
  • nginx 代理后面的 SpringDoc/Swagger

    我们正在运行一个服务nginx代理以便 http service post 8080 swagger ui html被路由到公共地址https host com services post swagger ui html 或者从另一种方式定
  • C# 使用泛型强制转换调用影子方法

    我正在尝试编写一种方法 将对象转换为泛型类型以执行特定的影子方法 这是我的测试代码 class Program static void Main string args hello2 h2 new hello2 test h2 Consol
  • 按钮的可重复使用的自定义内容

    我的用户界面使用定制的Buttons 它们都包含Image and a Label 我定制了一个单Button手动 通过将其内容设置为包含Image and a Label 但是 由于我需要有几个这样的Buttons 具有不同的图像和标签
  • 为什么 PlusClient.loadPeople 失败并出现 HTTP 403 错误?

    我将旧的 Google Plus 又名 Google Play 服务 API 集成到我的应用程序中 现在我正在尝试更新内容以使用 V2 API 其中包括访问某个人圈子中的人员列表等 表面上 我应该做的唯一更改是更新我用于身份验证的 OAut
  • 如何获取完整的关注者列表

    使用最新版本的推文尖锐库对于 twitter api 我试图获取特定用户的所有关注者 但我只能用这种方法获得最后 100 个关注者 IEnumerable
  • 一种样式选择器,用于指定特定类中的悬停、活动

    我正在尝试找出如何为以下内容编写样式 我只想为 menu 内的锚标记设置 a hover 和 a active 样式 而不是 menu switch 下面的代码似乎有效 但是我可以将它们合并为一种样式吗 Apply the followin
  • 在Python IDLE中,“打印”变量和仅写入变量有什么区别?

    在 IDLE 解释器中 我使用 dpkt 执行以下操作 for ts buf in pcap eth dpkt ethernet Ethernet buf 现在 当我尝试查看 eth 的内容时 我可以打印它 或者只写变量名 当我做 prin
  • lm() 中的 poly():原始与正交之间的差异

    I have library ISLR attach Wage Polynomial Regression and Step Functions fit lm wage poly age 4 data Wage coef summary f
  • LPCWSTR 代表什么以及应该如何处理?

    首先 它到底是什么 我猜它是一个指针 LPC表示长指针常量 但是 W 是什么意思 是指向字符串的特定指针还是指向特定字符串的指针 例如我想关闭一个名为 TestWindow 的窗口 HWND g hTest LPCWSTR a a Test
  • 在严格模式下获取未知环境中全局对象的引用

    获得句柄的推荐方法是什么全局对象在 ES5 严格模式下在未知的宿主环境中 ECMAScript 没有提供引用我所知道的全局对象的内置方法 如果是的话 这就是我正在寻找的答案 In a 已知环境 全局对象通常具有自引用属性 由于全局对象是VO
  • 将一个数组插入到另一个数组的每第 n 个元素中

    我有 2 个数组 a b c d e f g h i 我需要在第一个数组的每第二个 或第 n 个 元素之后插入第二个数组的元素 结果是 a b g c d h e f i 我有一个简单的方法可以做到这一点吗 您始终可以使用自定义Enumer
  • Django - 仅在 AppConfig.ready() 中创建一个类实例一次

    我需要在应用程序启动 runserver 上创建一个类实例 假设后端请求会话 并且我不想在运行其他管理命令后重写此会话 我怎样才能实现这个目标 我尝试了几种方法 但我不确定为什么这样的方法不起作用 app apps py class MyC
  • Python:从机模式下向mplayer发送命令

    在从属模式下运行 mplayer 时 我尝试通过管道向 mplayer 发送命令 如下所示 import subprocess time start mplayer song mysong mp3 cmd mplayer slave qui
  • 从 Singleton 接收 pyqtSignal

    python中有一个单例类 from PyQt5 QtCore import QObject pyqtSignal import logging class Singleton QObject instance None def new c
  • 如何在 Objective-C 中创建和使用队列?

    我想在我的 Objective C 程序中使用队列数据结构 在 C 中我会使用 STL 队列 Objective C 中等效的数据结构是什么 如何推送 弹出项目 Ben 的版本是堆栈而不是队列 所以我对其进行了一些调整 NSMutableA
  • Selenium:打开扩展的弹出窗口

    我正在尝试使用 Selenium 为我的扩展编写 E2E 测试 对于我的测试 我需要打开扩展程序的弹出页面 就好像用户单击扩展程序的徽标 位于浏览器的右下角 一样 我已经成功地使用扩展程序初始化了 ChromeDriver 方法是 Chro