javascript - Chrome onMessage监听器总是发送 'undefined'响应

标签 javascript google-chrome selenium google-chrome-extension browser-extension

我已经制作了可以使用消息传递的最基本的 Chrome 扩展。扩展程序应监听来自网站的消息(此处为 localhost:8080/*)并始终响应“再见”。在测试中,selenium 使用 chrome 打开本地服务的页面,该页面尝试向扩展发送消息,然后在控制台上抛出响应:

$ tree -I node_modules
.
├── extension
│   ├── background.js
│   └── manifest.json
├── package.json
└── test
    ├── index.html
    └── selenium-test.js

2 directories, 5 files

background.js

chrome.runtime.onMessage.addListener(
    function (req, sender, sendResp) {
        sendResp('Bye');
    });

manifest.json

{
    "name": "chrome-test",
    "version": "0.1",
    "manifest_version": 2,
    "key": "pcoogjpilcclcmejpkmbifdbihomlgec",
    "description": "Test extension.",
    "app": {
    "background": {
        "scripts": ["background.js"],
        "persistent": true
    }
    },
    "externally_connectable": {
    "matches": [
        "http://localhost:8080/*"
    ],
    "accepts_tls_channel_id": false
    },
    "permissions": [
    "http://localhost:8080/*"
    ]
}

package.json

{
    "name": "chrome-test",
    "version": "0.0.5",
    "description": "Chrome API sucks.",
    "keywords": [ "" ],
    "author": "Chris Perivolaropoulos",
    "contributors": [],
    "dependencies": {
    "selenium-webdriver": "*",
    "mocha": "*",
    "chai": "*"
    },
    "scripts": {
    "test": "mocha test/selenium-test.js"
    }
}

index.html

<html>
  <head>
    <title>Test page</title>
  </head>
  <body>
    <h1>Test page</h1>
    <div id="echo"></div>
    <script type="text/javascript">
      chrome.runtime.sendMessage('pcoogjpilcclcmejpkmbifdbihomlgec', 'hello',
      function (msg) {
      console.log("Received! " + msg);
      });
    </script>
  </body>
</html>

selenium-test.js

var assert = require('chai').assert,
    test = require('selenium-webdriver/testing'),
    webdriver = require('selenium-webdriver'),
    chromedriver = require('selenium-webdriver/chrome');

// @param extensions: string of unpacked extension path to install.
function chrome_driver(extension) {
    var logperfs = new webdriver.logging.Preferences(),
            opts = new chromedriver.Options().
                addArguments("--load-extension=" + extension ||
                                         '../extension');

    logperfs.setLevel(webdriver.logging.Type.BROWSER,
                                        webdriver.logging.Level.ALL);

    var chrome = new webdriver.Builder().
                withCapabilities(webdriver.Capabilities.chrome()).
                setChromeOptions(opts).
                setLoggingPrefs(logperfs).
                build();

    chrome.manage().timeouts().pageLoadTimeout(5000);
    return chrome;
}

function browser_logs(driver, callback) {
    driver.manage().logs().
        get(webdriver.logging.Type.BROWSER).then(callback);
}

test.describe('Test', function() {
    var chrome;
    this.timeout(10000);

    test.before(function() {
        chrome = chrome_driver("extension");
    });

    test.it("Test messages", function () {
        chrome.get("http://localhost:8080/test/index.html").then(function () {
            browser_logs(chrome, function (entries) {
                entries.forEach(function (e) {console.log("BrowserLog: " + e.message);});
                assert.equal(entries.pop().message,
                                         "hello", "Bus not echoing.");
            });
        });
    });

    test.after(function() {
        chrome.quit();
    });
});

要运行测试,首先运行本地 http 服务器

$ python -m SimpleHTTPServer 8080
Serving HTTP on 0.0.0.0 port 8080 ...

并从另一个控制台运行测试

$ npm test

> <a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="c5a6adb7aaa8a0e8b1a0b6b185f5ebf5ebf0" rel="noreferrer noopener nofollow">[email protected]</a> test /path/to/project
> mocha test/selenium-test.js



  Test
BrowserLog: http://localhost:8080/test/index.html 11:15 Received! undefined
[2K[0G    1) Test messages


  0 passing (1s)
  1 failing

  1) Test Test messages:

      Bus not echoing.
      + expected - actual

      +hello
      -http://localhost:8080/test/index.html 11:15 Receviced! undefined

      at /path/to/project/test/selenium-test.js:43:12
      at /path/to/project/node_modules/selenium-webdriver/lib/goog/base.js:1582:15
      at webdriver.promise.ControlFlow.runInNewFrame_ (/path/to/project/node_modules/selenium-webdriver/lib/webdriver/promise.js:1640:20)
      at notify (/path/to/project/node_modules/selenium-webdriver/lib/webdriver/promise.js:444:12)
      at notifyAll (/path/to/project/node_modules/selenium-webdriver/lib/webdriver/promise.js:422:7)
      at resolve (/path/to/project/node_modules/selenium-webdriver/lib/webdriver/promise.js:400:7)
      at fulfill (/path/to/project/node_modules/selenium-webdriver/lib/webdriver/promise.js:512:5)
      at Object.webdriver.promise.asap (/path/to/project/node_modules/selenium-webdriver/lib/webdriver/promise.js:758:5)
      at webdriver.promise.ControlFlow.runInNewFrame_ (/path/to/project/node_modules/selenium-webdriver/lib/webdriver/promise.js:1651:25)
      at notify (/path/to/project/node_modules/selenium-webdriver/lib/webdriver/promise.js:444:12)
      at notifyAll (/path/to/project/node_modules/selenium-webdriver/lib/webdriver/promise.js:422:7)
      at resolve (/path/to/project/node_modules/selenium-webdriver/lib/webdriver/promise.js:400:7)
      at fulfill (/path/to/project/node_modules/selenium-webdriver/lib/webdriver/promise.js:512:5)
      at Object.webdriver.promise.asap (/path/to/project/node_modules/selenium-webdriver/lib/webdriver/promise.js:758:5)
      at webdriver.promise.ControlFlow.runInNewFrame_ (/path/to/project/node_modules/selenium-webdriver/lib/webdriver/promise.js:1651:25)
      at notify (/path/to/project/node_modules/selenium-webdriver/lib/webdriver/promise.js:444:12)
      at notifyAll (/path/to/project/node_modules/selenium-webdriver/lib/webdriver/promise.js:422:7)
      at resolve (/path/to/project/node_modules/selenium-webdriver/lib/webdriver/promise.js:400:7)
      at fulfill (/path/to/project/node_modules/selenium-webdriver/lib/webdriver/promise.js:512:5)
      at /path/to/project/node_modules/selenium-webdriver/lib/webdriver/promise.js:1507:10
      at /path/to/project/node_modules/selenium-webdriver/lib/goog/base.js:1582:15
      at webdriver.promise.ControlFlow.runInNewFrame_ (/path/to/project/node_modules/selenium-webdriver/lib/webdriver/promise.js:1640:20)
      at notify (/path/to/project/node_modules/selenium-webdriver/lib/webdriver/promise.js:444:12)
      at notifyAll (/path/to/project/node_modules/selenium-webdriver/lib/webdriver/promise.js:422:7)
      at resolve (/path/to/project/node_modules/selenium-webdriver/lib/webdriver/promise.js:400:7)
      at fulfill (/path/to/project/node_modules/selenium-webdriver/lib/webdriver/promise.js:512:5)
      at /path/to/project/node_modules/selenium-webdriver/lib/goog/base.js:1582:15
      at webdriver.promise.ControlFlow.runInNewFrame_ (/path/to/project/node_modules/selenium-webdriver/lib/webdriver/promise.js:1640:20)
      at notify (/path/to/project/node_modules/selenium-webdriver/lib/webdriver/promise.js:444:12)
      at notifyAll (/path/to/project/node_modules/selenium-webdriver/lib/webdriver/promise.js:422:7)
      at resolve (/path/to/project/node_modules/selenium-webdriver/lib/webdriver/promise.js:400:7)
      at fulfill (/path/to/project/node_modules/selenium-webdriver/lib/webdriver/promise.js:512:5)
      at /path/to/project/node_modules/selenium-webdriver/lib/webdriver/promise.js:703:49
      at /path/to/project/node_modules/selenium-webdriver/lib/webdriver/http/http.js:96:5
      at IncomingMessage.<anonymous> (/path/to/project/node_modules/selenium-webdriver/http/index.js:131:7)
      at IncomingMessage.emit (events.js:117:20)
      at _stream_readable.js:943:16
      at process._tickCallback (node.js:419:13)
  ==== async task ====
  WebDriver.manage().logs().get(browser)
      at webdriver.WebDriver.schedule (/path/to/project/node_modules/selenium-webdriver/lib/webdriver/webdriver.js:302:15)
      at webdriver.WebDriver.Logs.get (/path/to/project/node_modules/selenium-webdriver/lib/webdriver/webdriver.js:1380:23)
      at browser_logs (/path/to/project/test/selenium-test.js:28:3)
      at /path/to/project/test/selenium-test.js:41:4
      at /path/to/project/node_modules/selenium-webdriver/lib/goog/base.js:1582:15
      at webdriver.promise.ControlFlow.runInNewFrame_ (/path/to/project/node_modules/selenium-webdriver/lib/webdriver/promise.js:1640:20)
      at notify (/path/to/project/node_modules/selenium-webdriver/lib/webdriver/promise.js:444:12)
      at notifyAll (/path/to/project/node_modules/selenium-webdriver/lib/webdriver/promise.js:422:7)
      at resolve (/path/to/project/node_modules/selenium-webdriver/lib/webdriver/promise.js:400:7)
      at fulfill (/path/to/project/node_modules/selenium-webdriver/lib/webdriver/promise.js:512:5)
      at Object.webdriver.promise.asap (/path/to/project/node_modules/selenium-webdriver/lib/webdriver/promise.js:758:5)
      at webdriver.promise.ControlFlow.runInNewFrame_ (/path/to/project/node_modules/selenium-webdriver/lib/webdriver/promise.js:1651:25)
      at notify (/path/to/project/node_modules/selenium-webdriver/lib/webdriver/promise.js:444:12)
      at notifyAll (/path/to/project/node_modules/selenium-webdriver/lib/webdriver/promise.js:422:7)
      at resolve (/path/to/project/node_modules/selenium-webdriver/lib/webdriver/promise.js:400:7)
      at fulfill (/path/to/project/node_modules/selenium-webdriver/lib/webdriver/promise.js:512:5)
      at /path/to/project/node_modules/selenium-webdriver/lib/webdriver/promise.js:1507:10
      at /path/to/project/node_modules/selenium-webdriver/lib/goog/base.js:1582:15
      at webdriver.promise.ControlFlow.runInNewFrame_ (/path/to/project/node_modules/selenium-webdriver/lib/webdriver/promise.js:1640:20)
      at notify (/path/to/project/node_modules/selenium-webdriver/lib/webdriver/promise.js:444:12)
      at notifyAll (/path/to/project/node_modules/selenium-webdriver/lib/webdriver/promise.js:422:7)
      at resolve (/path/to/project/node_modules/selenium-webdriver/lib/webdriver/promise.js:400:7)
      at fulfill (/path/to/project/node_modules/selenium-webdriver/lib/webdriver/promise.js:512:5)
      at /path/to/project/node_modules/selenium-webdriver/lib/goog/base.js:1582:15
      at webdriver.promise.ControlFlow.runInNewFrame_ (/path/to/project/node_modules/selenium-webdriver/lib/webdriver/promise.js:1640:20)
      at notify (/path/to/project/node_modules/selenium-webdriver/lib/webdriver/promise.js:444:12)
      at notifyAll (/path/to/project/node_modules/selenium-webdriver/lib/webdriver/promise.js:422:7)
      at resolve (/path/to/project/node_modules/selenium-webdriver/lib/webdriver/promise.js:400:7)
      at fulfill (/path/to/project/node_modules/selenium-webdriver/lib/webdriver/promise.js:512:5)
      at /path/to/project/node_modules/selenium-webdriver/lib/webdriver/promise.js:703:49
      at /path/to/project/node_modules/selenium-webdriver/lib/webdriver/http/http.js:96:5
      at IncomingMessage.<anonymous> (/path/to/project/node_modules/selenium-webdriver/http/index.js:131:7)
      at IncomingMessage.emit (events.js:117:20)
      at _stream_readable.js:943:16
      at process._tickCallback (node.js:419:13)
  ==== async task ====
      at Context.ret (/path/to/project/node_modules/selenium-webdriver/testing/index.js:132:12)
      at Test.Runnable.run (/path/to/project/node_modules/mocha/lib/runnable.js:216:15)
      at Runner.runTest (/path/to/project/node_modules/mocha/lib/runner.js:373:10)
      at /path/to/project/node_modules/mocha/lib/runner.js:451:12
      at next (/path/to/project/node_modules/mocha/lib/runner.js:298:14)
      at /path/to/project/node_modules/mocha/lib/runner.js:308:7
      at next (/path/to/project/node_modules/mocha/lib/runner.js:246:23)
      at Object._onImmediate (/path/to/project/node_modules/mocha/lib/runner.js:275:5)
      at processImmediate [as _immediateCallback] (timers.js:345:15)



npm ERR! Test failed.  See above for more details.

扩展程序始终响应 undefined而不是'Bye'按照 background.js 中的说明进行操作。

最佳答案

错误的事件。

从网页发送的消息via externally_connectable被视为外部消息。因此,您的后台脚本应该看起来 like this :

chrome.runtime.onMessageExternal.addListener(
  function (req, sender, sendResp) {
    sendResp('Bye');
  }
);

您会觉得监听器发送了未定义的响应,因为在以下两种情况之一中调用了 sendMessage 的回调:

  • 一个监听器实际上调用了sendResponse。然后将参数设置为该响应。
  • 发送消息时出错。那么参数是 undefined 并且 chrome.runtime.lastError 被设置。

您遇到了第二种情况 - 因为没有相应事件的监听器。

现在,一个单独的问题是网页上下文是否可以访问 chrome.runtime.lastError..

关于javascript - Chrome onMessage监听器总是发送 'undefined'响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26247514/

相关文章:

javascript - Chrome 不再允许输入类型 ="number"上的 selectionStart/selectionEnd

HTML5 输入类型编号 16 位或更多位 Chrome 替换为零

javascript - CanvasRenderingContext2D.drawImage() 在大 Canvas 上的 Chrome 中非常慢

selenium - 如何使用Selenium Webdriver中的xpath查找包含的文本的确切值?

css - 在 CSS3 中用什么代替 CONTAINS()

javascript - Jqgrid - 选择下拉菜单的验证

javascript - 如何使用 angularJS 将所​​有日期从 UTC 转换为本地时间?

javascript - 如何将 console.log() 结果存储为对象/变量?

javascript - s3 上传音频文件但无法播放。如何上传音频流到s3?

java - Selenium 在 IE 中的截图