我昨天将Chrome和Chromedriver更新到了最新版本,从那以后,我在运行Cucumber功能时收到了以下错误消息:
....
unknown error: Cannot construct KeyEvent from non-typeable key
(Session info: chrome=98.0.4758.80) (Selenium::WebDriver::Error::UnknownError)
#0 0x55e9ce6a4093 <unknown>
#1 0x55e9ce16a648 <unknown>
#2 0x55e9ce1a9866 <unknown>
#3 0x55e9ce1cbd29 <unknown>
.....
我尝试用Capybara的fill_in
方法填充一个文本字段。在调试时,我注意到Capybara有问题,尤其是符号@
和。每隔一个字符都可以毫无问题地写入文本字段。
触发错误的代码看起来像这个
def sign_in(user)
visit new_sign_in_path
fill_in 'Email', with: user.email
fill_in 'Password', with: user.password
click_button 'Sign in'
end
user.email
包含类似于"example1@mail.com"
的字符串。
我使用Rails 6.1.3.1、Cucumber 5.3.0、Chromedriver 98.0.4758.48、水豚3.35.3
该错误仅发生在用@javascript
标记的功能上
你知道是什么导致了这个错误,或者如何修复它吗?
目前最简单的方法是固定到早期版本的chrome驱动程序,因此将其添加到您的水豚配置中
在ruby中
# /test/support/system/capybara_config.rb
require 'webdrivers/chromedriver'
Webdrivers::Chromedriver.required_version = '97.0.4692.71'
希望这个问题将在未来的chromedriver版本中得到解决,它已经被提出并在这里讨论
我还尝试了重写fill_in
方法。
这并不理想,而且实际上取决于操作系统,所以请提供更好的解决方案或更新此答案。随着研究的进展,我会尽量更新。
class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
# overriding the `fill_in` helper for filling in strings with an `@` symbol
def fill_in(locator = nil, with:, currently_with: nil, fill_options: {}, **find_options)
return super unless with.include? "@"
find_options[:with] = currently_with if currently_with
find_options[:allow_self] = true if locator.nil?
element = find(:fillable_field, locator, **find_options)
email_front, email_back = with.split("@")
element.send_keys(email_front)
page.driver.browser.action
.key_down(Selenium::WebDriver::Keys[:alt])
.send_keys('g')
.key_up(Selenium::WebDriver::Keys[:alt])
.perform
element.send_keys(email_back)
end
end
新版本的ChromeDriver似乎发生了一些变化,不再可以直接使用send_keys方法发送一些特殊的字符。
在这个链接中,您将看到它是如何解决的(在C#中)-->Selenium-SendKeys("@")编写一个"à">
关于python的实现,请查看这一点-->https://www.geeksforgeeks.org/special-keys-in-selenium-python/
具体来说,我的实现是(使用MAC):
driver.find_element('.email-input', 'user@mail.com')
现在我不得不更改它:
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains
emailParts = 'user@mail.com'.split('@')
emailElement = driver.find_element('.email-input')
emailElement.send_keys(emailParts[0])
action = ActionChains(driver)
action.key_down(Keys.ALT).send_keys('2').key_up(Keys.ALT).perform()
emailElement.send_keys(emailParts[1])
我在使用Python时也遇到了同样的问题,似乎只使用ActionChains可以简单地解决问题。
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By
def safe_send_keys(
driver,
input_selector: str,
input_text: str,
selector_type = By.CSS_SELECTOR
):
driver.find_element(selector_type, input_selector).click()
action = ActionChains(driver)
action.send_keys(input_text)
action.perform()
# Example
driver = webdriver.Chrome()
# ... Go to your web page
email = "email_with_at@email.com"
selector = "input_selector"
safe_send_keys(driver, selector, email)
这个答案适用于Java和WebDriverManager用户
您可以在启动chrome之前指定这样的chrome驱动程序版本。
WebDriverManager.chromedriver().browserVersion("97").setup();
你可以解决这个问题。
更新
这个ChromeDriver错误已经修复了
我们今天和我的同事遇到了同样的问题。
对我们有效的是从Chrome设置中删除任何语言,但删除了英语(我也在使用波兰语,似乎这并不是问题的根源)。
机器:MacBook Pro与macOS蒙特利12.1;测试框架:Java 11/Selenium
Chrome v.98-语言设置
我对python也收到了同样的错误。如果谷歌chrome自动更新到98版本,也不要将chromedriver更新到98,请使用97。这解决了我的问题。
我在Java中使用Selenium。在谷歌Chrome更新之前,我一直在自动化登录功能,没有任何问题。更新后,我也开始出现同样的错误。我只是把我的键盘语言改成了";US";并且问题得到了解决。
更新:最近(2月中旬),我的ChromeDriver停止出现同样的错误。我不确定是否有修复,因为自从我开始出现问题以来,我没有看到新的版本,但我的Java/Senium自动化代码运行时没有任何错误,无论键盘语言如何,并发送像"@"这样的字符。因此,无需将键盘语言切换为";US";不再
我也有同样的问题。我为Selenium java解决了这个问题,比如:
String arroba = Keys.chord(Keys.ALT, "2");
String[] mailSplit = mail.split("@");
userInput.sendKeys(mailSplit[0]);
userInput.sendKeys(arroba);
userInput.sendKeys(Keys.BACK_SPACE);
userInput.sendKeys(mailSplit[1]);
只需使用JavascriptExecutor,例如:
JavascriptExecutor jse = (JavascriptExecutor) getDriver();
jse.executeScript("arguments[0].setAttribute('value', arguments[1])", googleEmailWebElement, email);
这是一个暂时的问题,有望在以后的版本中得到解决https://github.com/SeleniumHQ/selenium/issues/10318
使用JS填充字段的测试宏解决了我对等基本场景的需求(Ruby)
fill_in :user_email, with: user.email
测试宏:
def fill_in_chrome98_tmp_fix(locator, with:)
element = find(:fillable_field, locator)
dom_id = element.native.dom_attribute("id")
raise "No DOM ID" if dom_id.blank?
page.execute_script("document.getElementById('#{dom_id}').value = '#{with}'")
end
这个问题也影响了我。这个答案适用于Python。这就是我目前在django设置硒测试的方式。我的铬浏览器是快照版本98.0.4758.80。
@classmethod
def setUpClass(cls):
super().setUpClass()
options = webdriver.ChromeOptions()
options.add_argument('--no-sandbox') # Must be the very first option
options.add_argument('--headless')
options.add_argument('--disable-gpu')
options.add_argument('--disable-software-rasterizer')
options.add_argument('--disable-dev-shm-usage')
options.add_argument("--remote-debugging-port=9222")
options.add_argument("--no-default-browser-check")
options.add_argument("--no-first-run")
options.add_argument("--disable-default-apps")
s = Service(
ChromeDriverManager(
# version='98.0.4758.80',
# version='98.0.4758.48',
version='97.0.4692.71',
log_level=logging.WARNING,
chrome_type=ChromeType.CHROMIUM).install())
cls.selenium = webdriver.Chrome(
service=s,
options=options)
cls.selenium.implicitly_wait(1)
将Google Chrome从以前的版本:97.0.4692.99-1更新到最新的版本:98.0.4758.80-1也会影响我的代码。我正在使用Python,无法再发送@、^等字符。现在,我只是降级了谷歌浏览器的版本。它影响了这样一个结构:self.driver.find_element_by_id('id_password').send_keys(password),其中,例如password包含^。
链接到linux机器上chrome版本的简单降级:https://makandracards.com/makandra/486433-how-to-downgrade-google-chrome-in-ubuntu