Write tests using Chrome's virtual authenticator API
lgarron opened this issue · 4 comments
I've held off on writing thorough tests, because getting a good mock WebAuthn authenticator working was a bit daunting. However, Chrome's DevTools protocol now supports virtual authenticators: https://chromedevtools.github.io/devtools-protocol/tot/WebAuthn/
This should make it possible to write fairly robust tests.
I haven't set up a GitHub action testing using the DevTools protocol, so we could use some help if anyone is familiar with how to set that up.
Using Capybara and the webauthn gem, I was able to get integration tests working in a Rails environment. I thought I'd post it here for a kickstart (which testing-stack are you intending to use, by the way?).
To my surprise, recent versions of selenium/webdrivers support this out-of-the-box.
# Setup is only possible *after* an initial request (visit in Capybara) has been made.
visit '/login'
# Ensure same-origin
WebAuthn.configuration.origin = Capybara.current_session.server.base_url
# Enable virtual authenticators in browser
devtools = page.driver.browser.devtools
devtools.send_cmd 'WebAuthn.enable'
# Create an Authenticator
# See https://chromedevtools.github.io/devtools-protocol/tot/WebAuthn/#type-VirtualAuthenticatorOptions
options = {
protocol: :ctap2,
transport: :internal,
hasResidentKey: false, # Chrome should not have to reveal a list of existing virtual authenticator IDs.
# isUserConsenting: true, # Not sure, this option exists in selenium but not in chrome?
hasUserVerification: true,
isUserVerified: true,
}
attributes = record.devtools.send_cmd 'WebAuthn.addVirtualAuthenticator', options: options
id = attributes.dig('result', 'authenticatorId')
# Make sure to tear down after each test because it will interfere with further tests
devtools.send_cmd 'WebAuthn.removeVirtualAuthenticator', authenticatorId: id
devtools.send_cmd 'WebAuthn.disable'
Thanks to this commit it just got much simpler:
visit '/login'
options = ::Selenium::WebDriver::VirtualAuthenticatorOptions.new
page.driver.browser.add_virtual_authenticator(options)
click_on 'Start the registration ceremony using my new hardware key'
Thanks to this commit it just got much simpler:
Thanks!
Just to be transparent, though: In the interest of keeping this library as easy as possible to maintain for its limited remaining lifetime, I think any JS testing framework would be preferable over Ruby (or over any other separate language).
I completely agree, thanks for being clear. I just wanted to post this as a heads-up that selenium is in the progress of directly implementing those DevTools calls. Three months ago JS got them as well. Good luck!