无法从selenium execute_script访问chrome消息传递API

时间:2013-10-16 02:51:41

标签: javascript python google-chrome selenium

我需要从浏览器自动化脚本向chrome扩展名发送一个值。 我目前正在尝试这样做的方式是尝试从selenium调用chrome.runtime.sendMessage API以将某些值传递给chrome扩展程序。 python代码是:

import os
import time
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.chrome.options import Options



chrome_options = Options()
chrome_options.add_extension('/home/lurscher/plugin.crx')
browser = webdriver.Chrome(chrome_options=chrome_options)
browser.get(url)
browser.execute_script("chrome.runtime.sendMessage({someValue: "+str(args.value)+"}, function(response) { console.log('value sent. '+response)})")

我收到此错误:

Traceback (most recent call last):
  File "tools/selenium/open_page.py", line 17, in <module>
    browser.execute_script("chrome.runtime.sendMessage({someValue: "+str(args.value)+"}, function(response) { console.log('value sent. '+response)})")
  File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/webdriver.py", line 397, in execute_script
    {'script': script, 'args':converted_args})['value']
  File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/webdriver.py", line 165, in execute
    self.error_handler.check_response(response)
  File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/errorhandler.py", line 164, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.WebDriverException: Message: u"unknown error: Cannot call method 'sendMessage' of undefined\n  (Session info: chrome=28.0.1500.71)\n  (Driver info: chromedriver=2.1,platform=Linux 3.5.0-17-generic x86_64)" 
  

问题:   知道我做错了什么吗?

     

我需要从浏览器向chrome扩展程序发送一个值   自动化脚本。我该怎么做?

4 个答案:

答案 0 :(得分:1)

运行此代码时出现类似错误:(JavaScript)

this.driver.executeScript(function () {
    chrome.runtime.sendMessage('start');
});
WebDriverError: unknown error: Cannot read property 'sendMessage' of undefined

在我看来,chrome.runtime始终可用,无论您是在开发扩展程序还是仅浏览网页。 (打开一个Incognito窗口并在控制台中评估它;它就在那里。)所以它必须与WebDriver有关。

根据我在网站上收集的内容,您必须额外配置您的驱动程序: https://groups.google.com/forum/#!topic/chromedriver-users/7wF9EHF2jxQ

options.excludeSwitches('test-type'); // this makes chrome.runtime available
builder.setChromeOptions(options);

然而,这会使上述错误演变为:

WebDriverError: unknown error: Invalid arguments to connect.

这是因为您的测试页面正在尝试与您的扩展程序进行通信,这是根据Chrome规范不允许的,除非您在清单中声明该页面。 e.g:

"externally_connectable": {
    "matches": [
    "http://localhost:8000/mytest.html”
    ]
}

但是,您现在必须在sendMessage调用中包含扩展ID:

this.driver.executeScript(function () {
    chrome.runtime.sendMessage('kjnfjpehjfekjjhcgkodhnpfkoalhehl', 'start');
});

我认为这有点尴尬。

我建议MGR建议使用内容脚本来代理您的sendMessage调用,因为内容脚本没有对外部页面施加限制。

我所做的是从我的测试中触发一个事件,该事件将由调用sendMessage函数的内容脚本获取:

在你的测试中:

this.driver.executeScript(function () {
    var event = document.createEvent('HTMLEvents');
    event.initEvent('extension-button-click', true, true);
    document.dispatchEvent(event);
});

在清单中声明内容脚本:

"content_scripts": [
    { "matches": ["<all_urls>"], "js": ["content_script.js"] }
]

在content_script.js中:

document.addEventListener('extension-button-click', function () {
    chrome.runtime.sendMessage('start');
});

希望有所帮助

答案 1 :(得分:0)

正如例外消息所说,Cannot call method 'sendMessage' of undefined。 似乎chrome.runtime调用仅在Chrome扩展的contenxt中调用,而execute_script中执行的代码仅在您的页面的上下文中。

答案 2 :(得分:0)

这个问题可能有多个解决方案。但我建议使用内容脚本页面到您的扩展,并使用内容脚本中的函数进行通信。当内容脚本构成客户端部分时,您可以访问内容脚本中定义的功能,以便与扩展程序进行通信而不会出现任何问题。如果这不适合你,请告诉我。

答案 3 :(得分:0)

据我所知,你的selenium python代码要发送数据到谷歌chromes扩展。这不可能。您没有权限,Chrome也不会允许您这样做。除非您创建一些隐藏的html元素,例如任何具有id ='message'的元素,并在数据属性中发送参数或作为元素的值。并在您的Google Chrome扩展程序中创建内容脚本,该内容将在页面加载后注入。将内容脚本注入页面后,您可以通过给定的ID获取参数。