【问题标题】:Chrome onMessage listener always sends 'undefined' responseChrome onMessage 侦听器始终发送“未定义”响应
【发布时间】:2014-12-02 13:25:29
【问题描述】:

我已经制作了可以使用消息传递的最基本的 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

> chrome-test@0.0.5 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.

按照 background.js 中的说明,扩展程序总是 响应 undefined 而不是 'Bye'

【问题讨论】:

  • 我觉得你很困惑。 onMessage:从扩展进程或内容脚本发送消息时触发。 developer.chrome.com/extensions/runtime#event-onMessage
  • 嗯,是的,它也可以用sendResp 发送一个回复。为了清楚起见,我将响应从“你好”更改为“再见”。

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


【解决方案1】:

错误的事件。

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

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

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

  • 实际上称为sendResponse 的侦听器。然后将参数设置为该响应。
  • 发送消息时出错。那么参数是undefined 并设置了chrome.runtime.lastError

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

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

【讨论】:

  • 成功了,非常感谢。编辑:是的,看起来网页可以访问lastError
猜你喜欢
  • 1970-01-01
  • 2012-06-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-25
  • 1970-01-01
  • 1970-01-01
  • 2022-07-14
相关资源
最近更新 更多