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 并简单地添加了一个点击我的测试用例中的事件。

希望这对卡在同一个地方的人有所帮助。