Selenium-chromedriver:无法从不可键入的键构造 KeyEvent
Selenium-chromedriver: Cannot construct KeyEvent from non-typeable key
我昨天将我的 Chrome 和 Chrome 驱动程序更新到最新版本,从那时起,我在 运行 我的 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,Chrome驱动程序 98.0.4758.48,水豚 3.35.3
错误仅发生在标记为 @javascript
的要素上
您知道导致此错误的原因或解决方法吗?
新版本的 ChromeDriver 似乎发生了一些变化,无法再使用 send_keys 方法直接发送一些特殊字符。
在此 link 中,您将看到它是如何解决的(在 C# 中)-->
关于 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])
目前最简单的方法是 固定到早期版本的 chrome 驱动程序,因此将其添加到您的水豚配置中
在ruby
# /test/support/system/capybara_config.rb
require 'webdrivers/chromedriver'
Webdrivers::Chromedriver.required_version = '97.0.4692.71'
希望这个问题将在未来的 chrome 驱动程序版本中得到解决,它有 been raised and is discussed here
我还尝试重写 fill_in
方法。
这不太理想,实际上 OS 依赖,所以请提供更好的解决方案或更新此答案。随着我研究的进展,我会尽量更新。
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
我有同样的问题。我为 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]);
我遇到了与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)
更新 Google Chrome 从上一版本:97.0.4692.99-1 到最新版本:98.0。 4758.80-1 也影响我的代码。
我正在使用 Python,但我无法发送更多的字符如 @、^。
目前,我只是简单地降级GoogleChrome的版本。
它影响了这样的结构:
self.driver.find_element_by_id('id_password').send_keys(密码),例如密码包含 ^.
Link 到 linux 机器上 chrome 版本的简单降级:
https://makandracards.com/makandra/486433-how-to-downgrade-google-chrome-in-ubuntu
就用JavascriptExecutor,例如:
JavascriptExecutor jse = (JavascriptExecutor) getDriver();
jse.executeScript("arguments[0].setAttribute('value', arguments[1])", googleEmailWebElement, email);
今天我的 co-worker 遇到了同样的问题。
对我们有用的是从 Chrome 设置中删除任何语言,但英语(我也在使用波兰语,似乎它不会导致问题)。
机器:装有 macOS Monterey 12.1 的 MacBook Pro;测试框架:Java 11/Selenium
Chrome v.98 - Language settings
此答案适用于 Java 和 WebDriverManager 用户。
您可以在开始前像这样指定 chrome 驱动程序版本 chrome。
WebDriverManager.chromedriver().browserVersion("97").setup();
您可以解决此问题。
更新
希望这是一个临时问题,会在以后的版本中解决
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 中设置硒测试的方式。我的 chromium 浏览器是 snap 版本 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)
我在 python 中遇到了同样的错误。如果 Google chrome 自动更新到版本 98,请不要将您的 chrome 驱动程序也更新到 98,use 97 instead。这解决了我的问题。
我在 Java 中使用 Selenium。在 Google Chrome 更新之前,我一直在自动化登录功能,没有任何问题。更新后,我也开始遇到同样的错误。我刚刚将键盘语言更改为“美国”,问题就解决了。
更新:最近(mid-February)我的 Chrome 驱动程序停止给出同样的错误。我不确定是否有修复,因为自从我开始遇到问题以来我没有看到新版本,但我的 Java/Selenium 自动化代码 运行 没有任何错误,无论键盘语言如何,发送字符如'@'。因此,无需再将键盘语言切换为“美国”。
我昨天将我的 Chrome 和 Chrome 驱动程序更新到最新版本,从那时起,我在 运行 我的 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,Chrome驱动程序 98.0.4758.48,水豚 3.35.3
错误仅发生在标记为 @javascript
您知道导致此错误的原因或解决方法吗?
新版本的 ChromeDriver 似乎发生了一些变化,无法再使用 send_keys 方法直接发送一些特殊字符。
在此 link 中,您将看到它是如何解决的(在 C# 中)-->
关于 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])
目前最简单的方法是 固定到早期版本的 chrome 驱动程序,因此将其添加到您的水豚配置中
在ruby
# /test/support/system/capybara_config.rb
require 'webdrivers/chromedriver'
Webdrivers::Chromedriver.required_version = '97.0.4692.71'
希望这个问题将在未来的 chrome 驱动程序版本中得到解决,它有 been raised and is discussed here
我还尝试重写 fill_in
方法。
这不太理想,实际上 OS 依赖,所以请提供更好的解决方案或更新此答案。随着我研究的进展,我会尽量更新。
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
我有同样的问题。我为 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]);
我遇到了与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)
更新 Google Chrome 从上一版本:97.0.4692.99-1 到最新版本:98.0。 4758.80-1 也影响我的代码。 我正在使用 Python,但我无法发送更多的字符如 @、^。 目前,我只是简单地降级GoogleChrome的版本。 它影响了这样的结构: self.driver.find_element_by_id('id_password').send_keys(密码),例如密码包含 ^.
Link 到 linux 机器上 chrome 版本的简单降级: https://makandracards.com/makandra/486433-how-to-downgrade-google-chrome-in-ubuntu
就用JavascriptExecutor,例如:
JavascriptExecutor jse = (JavascriptExecutor) getDriver();
jse.executeScript("arguments[0].setAttribute('value', arguments[1])", googleEmailWebElement, email);
今天我的 co-worker 遇到了同样的问题。
对我们有用的是从 Chrome 设置中删除任何语言,但英语(我也在使用波兰语,似乎它不会导致问题)。
机器:装有 macOS Monterey 12.1 的 MacBook Pro;测试框架:Java 11/Selenium
Chrome v.98 - Language settings
此答案适用于 Java 和 WebDriverManager 用户。
您可以在开始前像这样指定 chrome 驱动程序版本 chrome。
WebDriverManager.chromedriver().browserVersion("97").setup();
您可以解决此问题。
更新
希望这是一个临时问题,会在以后的版本中解决 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 中设置硒测试的方式。我的 chromium 浏览器是 snap 版本 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)
我在 python 中遇到了同样的错误。如果 Google chrome 自动更新到版本 98,请不要将您的 chrome 驱动程序也更新到 98,use 97 instead。这解决了我的问题。
我在 Java 中使用 Selenium。在 Google Chrome 更新之前,我一直在自动化登录功能,没有任何问题。更新后,我也开始遇到同样的错误。我刚刚将键盘语言更改为“美国”,问题就解决了。
更新:最近(mid-February)我的 Chrome 驱动程序停止给出同样的错误。我不确定是否有修复,因为自从我开始遇到问题以来我没有看到新版本,但我的 Java/Selenium 自动化代码 运行 没有任何错误,无论键盘语言如何,发送字符如'@'。因此,无需再将键盘语言切换为“美国”。