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