Reputation:
I updated my Chrome and Chromedriver to the latest version yesterday, and since then I get the following error messages when running my Cucumber features:
....
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>
.....
I try to fill a text field with Capybara's fill_in
method. While debugging I noticed that Capybara has problems especially with the symbols @
and \
. Every other character can be written into the text field without any problems.
The code that triggers the error looks like this
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
contains a string like "[email protected]"
.
I work with Rails 6.1.3.1, Cucumber 5.3.0, Chromedriver 98.0.4758.48, capybara 3.35.3
The error only occurs on features that are tagged with @javascript
Do you have any ideas what causes this error or how to fix it?
Upvotes: 29
Views: 7980
Reputation: 3002
You can specify chrome driver version like this before start chrome.
WebDriverManager.chromedriver().browserVersion("97").setup();
You can work around this problem.
This ChromeDriver bug has fixed
Upvotes: 3
Reputation: 21
I am using Selenium with Java. I have been automating login functions without any problem until the Google Chrome update. After the update, I started getting the same error as well. I just changed my keyboard language to "US" and the problem is solved.
Update: Recently (mid-February) my ChromeDriver stopped giving the same error. I am not sure if there has been a fix as I didn't see a new release since I started having problems but my Java/Selenium automation codes run without any error regardless of the keyboard language and send characters like '@'. So, no need to switch the keyboard language to "US" anymore.
Upvotes: 2
Reputation: 4415
For now the easiest is to pin to an earlier version of the chrome driver, so add this to your capybara config
In ruby
# /test/support/system/capybara_config.rb
require 'webdrivers/chromedriver'
Webdrivers::Chromedriver.required_version = '97.0.4692.71'
Hopefully this issue will be addressed in future chromedriver releases, it has been raised and is discussed here
I also played around with overriding the fill_in
method.
This is less than ideal, and actually OS dependent, so please provide better solution or update this answer. I will try to update as my research progresses.
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
Upvotes: 12
Reputation: 793
I was getting the same error for python. If Google chrome automatically updated to version 98 don't update your chromedriver to 98 also, use 97 instead. This solved my issue.
Upvotes: 2
Reputation: 13
This issue affected me as well. This answer is for Python. This is how I currently set up my selenium tests in django. My chromium browser is snap version 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)
Upvotes: 1
Reputation: 5847
This is hopefully a temporary problem that will be solved in a later release https://github.com/SeleniumHQ/selenium/issues/10318
A test macro using JS to fill in the field solved my needs (Ruby) for basic scenarios like
fill_in :user_email, with: user.email
Test macro:
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
Upvotes: 1
Reputation: 21
We had the same issue with my co-worker today.
What worked for us was removing any language from the Chrome settings, but the English (I'm using the Polish language as well and it seems like it's not causing the issue).
Machine: MacBook Pro with macOS Monterey 12.1; Test Framework: Java 11/Selenium
Chrome v.98 - Language settings
Upvotes: 2
Reputation: 55
Just use JavascriptExecutor, for example:
JavascriptExecutor jse = (JavascriptExecutor) getDriver();
jse.executeScript("arguments[0].setAttribute('value', arguments[1])", googleEmailWebElement, email);
Upvotes: 1
Reputation: 171
Update of Google Chrome from the previous Version: 97.0.4692.99-1 to the newest one Version: 98.0.4758.80-1 also affect my code. I am using Python and I couldn't send any more characters as @, ^. For now, I simply downgrade the version of Google Chrome. It affected on such a structure: self.driver.find_element_by_id('id_password').send_keys(password), where e.g. password contains ^.
Link to a simple downgrade of chrome version on linux machines: https://makandracards.com/makandra/486433-how-to-downgrade-google-chrome-in-ubuntu
Upvotes: 0
Reputation: 71
I had the same problem with Python, and it seems that using only ActionChains solves the problem in an easy way.
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 protected]"
selector = "input_selector"
safe_send_keys(driver, selector, email)
Upvotes: 3
Reputation: 11
I have same problem. I solved it for Selenium java like:
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]);
Upvotes: 1
Reputation: 201
It seems something has changed in the new version of ChromeDriver and it is no longer possible to send some special chars directly using send_keys method.
In this link you will see how it is solved (in C#) --> Selenium - SendKeys("@") write an "à"
And regarding python implementation, check this out --> https://www.geeksforgeeks.org/special-keys-in-selenium-python/
Specifically, my implementation was (using MAC):
driver.find_element('.email-input', '[email protected]')
Now I had to change it by:
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains
emailParts = '[email protected]'.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])
Upvotes: 3