Chrome 扩展内容脚本消息传递反应应用程序无法在 Cypress 环境中运行
Chrome extension content script messaging react application not working in Cypress environment
我正在开发 Chrome 扩展,它在本地按预期工作。
当我在 Cypress 测试浏览器中加载扩展程序并确保它处于打开状态时,扩展程序似乎没有执行任何操作。
这是一个 MWE:
public/manifest.json
{
"manifest_version": 2,
"name": "name",
"version": "0.1.0",
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["content.js"]
}
],
"background": {
"scripts": ["background.js"]
},
"permissions": ["tabs", "http://*/"],
"browser_action": {
"default_icon": "logo192.png",
"default_title": "title"
}
}
public/content.js
// background script sends a response once it receives a message from App.js (see below)
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
window.postMessage({ msg: "hi" }, "http://localhost:3000");
});
src/App.js
import React, { useEffect } from "react";
import "bootstrap/dist/css/bootstrap.min.css";
import { Button } from "react-bootstrap";
export default function App() {
useEffect(() => {
function triggerEvent(e) {
if (e.source !== window) return;
alert("here");
}
window.addEventListener("message", (e) => triggerEvent(e));
// cleanup event listener
return () => {
window.removeEventListener("message", (e) => triggerEvent(e));
};
});
function sendMessage() {
chrome.runtime.sendMessage("extension_id", {msg: "hi"});
}
return (
<Button id="amazing-btn" variant="primary" type="button" onClick={()=>sendMessage()}>
button
</Button>
);
}
cypress.json
{
"baseUrl": "http://localhost:3000"
}
cypress/plugins/index.js
/// <reference types="cypress" />
module.exports = (on, config) => {
require("@cypress/code-coverage/task")(on, config);
// load extension into cypress browser
on("before:browser:launch", (browser, launchOptions) => {
launchOptions.extensions.push("full/path/to/my/public/folder");
return launchOptions;
});
return config;
};
我检查了一下,这在 Cypress 的测试浏览器中正确加载并打开了扩展程序。
cypress/integration/App.spec.js
/// <reference types="cypress" />
describe("App Tests", () => {
beforeEach(() => {
cy.visit(Cypress.config().baseUrl);
});
it("renders everything", () => {
cy.get("#amazing-btn");
});
it("clicks button", () => {
// should see an alert in the Cypress timeline after click, but none is shown
cy.get("#amazing-btn").click();
});
});
问题:
在 cypress 浏览器(不是本地)上,内容脚本似乎没有正确地将消息发送到 React 应用程序,因为我没有看到任何来自应用程序端的警报(App.js)。
最让我困惑的是,这在本地有效,但在 cypress 浏览器中无效。我确实看到我的后台脚本能够与内容脚本(在赛普拉斯中)通信,但是内容和应用程序之间的最后一座桥梁阻止我继续测试。
知道为什么会这样吗?
我想出了如何绕过按钮点击直接通过 Cypress 将消息发送到我的 React 应用程序和存根信息并且它有效!
为了完成覆盖,我将我的代码修改为不 运行 函数,如果发送消息的 window 包含 cypress 浏览器 URL 并简单地添加了一个点击我的测试用例中的事件。
希望这对卡在同一个地方的人有所帮助。
我正在开发 Chrome 扩展,它在本地按预期工作。 当我在 Cypress 测试浏览器中加载扩展程序并确保它处于打开状态时,扩展程序似乎没有执行任何操作。
这是一个 MWE:
public/manifest.json
{
"manifest_version": 2,
"name": "name",
"version": "0.1.0",
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["content.js"]
}
],
"background": {
"scripts": ["background.js"]
},
"permissions": ["tabs", "http://*/"],
"browser_action": {
"default_icon": "logo192.png",
"default_title": "title"
}
}
public/content.js
// background script sends a response once it receives a message from App.js (see below)
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
window.postMessage({ msg: "hi" }, "http://localhost:3000");
});
src/App.js
import React, { useEffect } from "react";
import "bootstrap/dist/css/bootstrap.min.css";
import { Button } from "react-bootstrap";
export default function App() {
useEffect(() => {
function triggerEvent(e) {
if (e.source !== window) return;
alert("here");
}
window.addEventListener("message", (e) => triggerEvent(e));
// cleanup event listener
return () => {
window.removeEventListener("message", (e) => triggerEvent(e));
};
});
function sendMessage() {
chrome.runtime.sendMessage("extension_id", {msg: "hi"});
}
return (
<Button id="amazing-btn" variant="primary" type="button" onClick={()=>sendMessage()}>
button
</Button>
);
}
cypress.json
{
"baseUrl": "http://localhost:3000"
}
cypress/plugins/index.js
/// <reference types="cypress" />
module.exports = (on, config) => {
require("@cypress/code-coverage/task")(on, config);
// load extension into cypress browser
on("before:browser:launch", (browser, launchOptions) => {
launchOptions.extensions.push("full/path/to/my/public/folder");
return launchOptions;
});
return config;
};
我检查了一下,这在 Cypress 的测试浏览器中正确加载并打开了扩展程序。
cypress/integration/App.spec.js
/// <reference types="cypress" />
describe("App Tests", () => {
beforeEach(() => {
cy.visit(Cypress.config().baseUrl);
});
it("renders everything", () => {
cy.get("#amazing-btn");
});
it("clicks button", () => {
// should see an alert in the Cypress timeline after click, but none is shown
cy.get("#amazing-btn").click();
});
});
问题:
在 cypress 浏览器(不是本地)上,内容脚本似乎没有正确地将消息发送到 React 应用程序,因为我没有看到任何来自应用程序端的警报(App.js)。
最让我困惑的是,这在本地有效,但在 cypress 浏览器中无效。我确实看到我的后台脚本能够与内容脚本(在赛普拉斯中)通信,但是内容和应用程序之间的最后一座桥梁阻止我继续测试。
知道为什么会这样吗?
我想出了如何绕过按钮点击直接通过 Cypress 将消息发送到我的 React 应用程序和存根信息并且它有效!
为了完成覆盖,我将我的代码修改为不 运行 函数,如果发送消息的 window 包含 cypress 浏览器 URL 并简单地添加了一个点击我的测试用例中的事件。
希望这对卡在同一个地方的人有所帮助。