【问题标题】:Firefox extension. How to access "browser" namespace from console?火狐扩展。如何从控制台访问“浏览器”命名空间?
【发布时间】:2018-07-05 20:15:07
【问题描述】:

我正在尝试使用控制台访问“浏览器”环境,例如browser.cookies.getAll 但除了扩展环境之外,它没有在任何地方定义。

如果使用浏览器 API 请求的 .js 文件制作简单的 firefox 插件(扩展): browser.cookies.getAll({}).then(console.log);

获取具有交互式预览的数组。

从扩展执行

如果在控制台执行此命令

如何从控制台访问“浏览器”命名空间?

【问题讨论】:

  • 您是否正在尝试使用它来测试您的扩展并对其进行调试?如果是这样,我可能有一个解决方案。出于安全原因,扩展上下文受到保护。无法从控制台中的命令访问它。
  • 是的,我测试了扩展并调试了它。你有什么解决方案?创建用于执行命令的扩展?))
  • 我的解决方案涉及到一点关于 Javascript 测试的知识。你知道任何测试框架吗?例如 jest、chai、mocha... 如果是这样,您可以模拟 browser.anyCommand 并将其作为 nodejs 脚本执行。这将帮助您确保您的扩展程序按预期工作,而无需在浏览器控制台上进行测试。如果您想要一个详细的示例,请告诉我,我会发布答案。这就是我测试我的扩展程序的方式,我不必每次更改代码时都在浏览器中重新加载扩展程序。
  • 请注意,您不能从控制台执行浏览器命令,它是一个安全卫士。从控制台执行时,浏览器命令比普通的 Javascript 代码更强大。唯一的方法是编写一个脚本,然后将其注入您的页面,然后执行该脚本。但这不是一个好主意。一个好的解决方案是 TDD(测试驱动开发)方法。
  • 是的,我知道测试框架,但没有使用它们。给你详细的例子。当有更多经验时,我将尝试在实践中应用或返回您的解决方案。 不必每次更改代码时都在浏览器中重新加载扩展 - 我喜欢它

标签: javascript firefox firefox-addon firefox-addon-sdk firefox-addon-webextensions


【解决方案1】:

这是不可能的,browser.*chrome.* 在开发者控制台上不可用,因为它们需要扩展的上下文来运行,而开发者控制台在当前页面的上下文中运行命令。

以下方法需要学习/了解 JavaScript 和 node.js 中的单元测试和集成测试,提供的示例过于简化,这绝不是生产就绪代码。


测试扩展和调试它的更好方法是为它编写测试。

  1. 选择一个测试框架(Jest、Mocha + chai 等)并根据需要进行设置

  2. 安装 sinon-chrome 包,通过运行 npm install --save-dev sinon-chrome

  3. browser.* 方法/api 提供 存根
  4. (可选)安装 webextensions-api-fake,它通过运行 npm install --save-dev webextensions-api-fake

  5. browser.* 方法/api 提供 mocks
  6. (可选)安装 webextensions-jsdom,它可以帮助您为 browser_action default_popup、sidebar_action default_panel 或后台页面/脚本编写测试

  7. 按照以下示例开始编写测试

  8. 为了调试您的扩展,在您选择的 IDE/编辑器中设置一个断点并运行测试,执行将在断点处停止,您将可以访问当时的对象和变量的状态执行。这将帮助您了解执行的内容和方式,以及您在函数中传递的数据发生了什么情况。无需在各处编写 console.log 语句来检查您的输出或变量,调试器可以提供帮助。

  9. (可选)webextensions-toolbox 是另一个用于编写具有相同代码库的跨浏览器扩展(您的扩展将在 chrome、firefox、opera、edge 上工作)的好工具。这还伴随着您的扩展程序 page 的热重载,因此您不必在每次进行任何更改时都点击刷新。

通过采用这种方法,它将改善您的开发工作流程,并减少您必须在浏览器上点击刷新的次数。

使用 jest 测试框架使用 sinon-chrome 存根的示例。
假设您已经在yourModule.js 中编写了代码,然后测试/验证它是否适用 yourModule.test.js你写的:

import browser from 'sinon-chrome';
import yourModule from './lib/yourModule';

describe('moduleName', () => {
  beforeAll(() => {
    // To make sure yourModule uses the stubbed version
    global.browser = browser;
  });
  it('does something', async () => {
    await yourModule();
    // Lets assume your module creates two tabs
    expect(browser.tabs.create.calledTwice).toBe(true);
    // If you want to test how those browser methods where called
    expect(browser.tabs.create.firstCall.calledWithExactly({
      url: 'https://google.com',
    })).toBe(true);
    // Notice the usage of `.firstCall` here, this makes sure only the first time 
    // `browser.tabs.create` was called with the given args.
  });
});

当您使用 jest 运行此测试时,yourModule 将期望存在一个全局变量 browser 及其使用的 api,这仅在真实浏览器中才有可能,但我们使用 sinon-chrome 包伪造它,您的模块将按预期在 node.js 环境中执行。

您无需在浏览器中运行它即可查看更改。您只需编写测试,编写代码以通过这些测试以及所有测试通过时。通过在浏览器中运行它来检查您的扩展程序,此时您的扩展程序将按照您的预期运行。如果您向您的模块添加另一个功能并且您的测试失败了,您就知道出了什么问题。

但是,上面的示例仅确定如何调用 browser.* 方法/api,以便您测试 yourModule 的行为,您需要模拟这些方法/api,这是 webextensions-api-fake 包你可以在 github 上的 repo 中找到example

github 上的 webextensions-jsdom 存储库中还提供了用于测试 browser_action default_popup、sidebar_action default_panel 或背景页面/脚本的示例。

【讨论】:

  • 这个答案包含一堆不需要的信息。问题是关于如何访问“浏览器”命名空间,而不是关于 JavaScript 模拟框架。访问该命名空间还有其他用途,比如控制您自己的浏览器。请注意,还有“浏览器工具箱”东西:developer.mozilla.org/en-US/docs/Tools/Browser_Toolbox,但也无法从那里访问“浏览器”。
  • OP 想要从开发者控制台中的选项卡上下文访问 browser.* api。 OP 的原因是测试他们的扩展。这些 api 仅在真实浏览器的扩展上下文中可用,所以我提供了一个替代方案。如果您打算使用这些 api 来玩它们,您可以这样做 1. 转到 about:addons 2. 从齿轮图标-> 调试插件或直接访问 about:debugging#/runtime/this-firefox 3 . 选择您已安装的任何扩展或创建虚拟 4. 单击检查。您将拥有熟悉的开发者控制台和 browser.* api 可用
  • 感谢@user6552940 提供如此详尽的回答!
猜你喜欢
  • 2022-06-11
  • 1970-01-01
  • 2014-09-03
  • 1970-01-01
  • 2010-12-11
  • 2017-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多