这是不可能的,browser.* 或 chrome.* 在开发者控制台上不可用,因为它们需要扩展的上下文来运行,而开发者控制台在当前页面的上下文中运行命令。
以下方法需要学习/了解 JavaScript 和 node.js 中的单元测试和集成测试,提供的示例过于简化,这绝不是生产就绪代码。
测试扩展和调试它的更好方法是为它编写测试。
选择一个测试框架(Jest、Mocha + chai 等)并根据需要进行设置
安装 sinon-chrome 包,通过运行 npm install --save-dev sinon-chrome
为 browser.* 方法/api 提供 存根
(可选)安装 webextensions-api-fake,它通过运行 npm install --save-dev webextensions-api-fake
为 browser.* 方法/api 提供 mocks
(可选)安装 webextensions-jsdom,它可以帮助您为 browser_action default_popup、sidebar_action default_panel 或后台页面/脚本编写测试
按照以下示例开始编写测试
为了调试您的扩展,在您选择的 IDE/编辑器中设置一个断点并运行测试,执行将在断点处停止,您将可以访问当时的对象和变量的状态执行。这将帮助您了解执行的内容和方式,以及您在函数中传递的数据发生了什么情况。无需在各处编写 console.log 语句来检查您的输出或变量,调试器可以提供帮助。
(可选)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 或背景页面/脚本的示例。