-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Declare Session#send_keys
#2422
Conversation
bcd66ed
to
a183b3b
Compare
@@ -303,6 +303,10 @@ def go_forward | |||
driver.go_forward | |||
end | |||
|
|||
def send_keys(*args, **kw_args) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a way to share documentation with the Node#send_keys
version, or would we need to declare comment docs here as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just link to Node#send_keys docs (See ...)
I need to check but I think the selenium api might provide access to the active element which would be preferable to use instead of evaluate_script |
a183b3b
to
8c5370a
Compare
5b1c1ee
to
0da8108
Compare
Along with the current code |
806fb2c
to
35bcecd
Compare
@@ -303,6 +303,14 @@ def go_forward | |||
driver.go_forward | |||
end | |||
|
|||
## | |||
# @!method send_keys | |||
# @see Capybara::Node::Element#send_keys |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@twalpole is this the correct Rubydoc syntax to link?
35bcecd
to
7e47e56
Compare
lib/capybara/rack_test/driver.rb
Outdated
@@ -50,6 +50,10 @@ def refresh | |||
browser.refresh | |||
end | |||
|
|||
def send_keys(*) | |||
raise Capybara::NotSupportedByDriverError, "RackTest driver doesn't have the concept of an active element, please call send_keys on a specific element" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@twalpole I've updated this error with the message you've suggested.
Reading it back: is it true that Rack Test supports key handlers?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch -- I hadn't thought that through -- no it doesn't, and calling send_keys
on an element would just raise a NotImplementedError, so this might as well be the same via the Capybara::Driver::Base default -- sorry about that.
35eb1e3
to
571d35b
Compare
@@ -133,6 +133,10 @@ def evaluate_async_script(script, *args) | |||
unwrap_script_result(result) | |||
end | |||
|
|||
def send_keys(*args) | |||
active_element.send_keys(*args) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@twalpole there is a test failure in CI:
1) Capybara::Session with remote Chrome with selenium driver #send_keys defaults to sending keys to the document.activeElement
Failure/Error: raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#send_keys'
Capybara::NotSupportedByDriverError:
Capybara::Driver::Base#send_keys
Shared Example Group: "Capybara::Session" called from ./spec/selenium_spec_chrome_remote.rb:73
# ./lib/capybara/driver/base.rb:63:in `send_keys'
# ./lib/capybara/session.rb:311:in `send_keys'
# ./lib/capybara/dsl.rb:58:in `block (2 levels) in <module:DSL>'
# ./spec/shared_selenium_session.rb:231:in `block (4 levels) in <top (required)>'
It seems like there are Selenium-enabled tests that are not using the Selenium::Driver
, and appear to be using Driver::Base
or RackTest::Driver
. Are the tests I've added missing a crucial setup step?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@seanpdoyle You'll need to tag the test(s) as requiring send_keys - like https://github.com/teamcapybara/capybara/blob/master/lib/capybara/spec/session/node_spec.rb#L1062 - although I am curious why the remote chrome driver version of the test would be failing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OH - I see the issue - your test isn't calling send_keys
on the session - https://github.com/teamcapybara/capybara/pull/2422/files#diff-0794c7a2e4cba5e9448e4dfb1bd723358f79c2e7a1a3a0fc879c6a8e86e793c6R231
This is triggering the creation of a new default session which defaults to the RackTest driver
Changing to session.send_keys(:tab)
should make the test correct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤦 , thank you!
With the way that the DSL module delegates to #page
, will that style of invocation work in consumer applications' test suites (outside this test suite)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes -- it's just that in the tests the session is passed in rather than letting a default one be created since it makes it easier for testing against multiple drivers or with multiple sessions. In most users case they're working with Capybara.current_session
and wouldn't be passing the actual session around.
When covering hotkeys and tab-navigation with test coverage, sending keys via particular elements (via `Node#send_keys`) can be tedious. As an alternative, invoke `Session#send_keys` to delegate to the element with current focus. In most (all?) browsers, `document.activeElement` will return the `<body>` element when there are no elements with focus. In Selenium-enabled environments, `Session#send_keys` delegates to the current element with focus (via [document.activeElement][]). Selenium-Webdriver provides a public method for reading the browser's active element, so use that in place of `Driver#evaluate_script`. In Rack Test environments, `Session#send_keys` raises an error. [active_element]: https://www.selenium.dev/documentation/en/webdriver/web_element/#get-active-element [document.activeElement]: https://developer.mozilla.org/en-US/docs/Web/API/DocumentOrShadowRoot/activeElement
90030e0
to
4e78e76
Compare
Thank you |
* master: Protect against optimization returning nil Update CI config for Ruby 3.0 release and update rubocop Wrapping injected disable_animation script in CDATA to prevent XHTML/XML parser errors History.md: fix typo [ci skip] Gem updates Update History.md for release date Update README for 3.34 [ci skip] Update History.md and version to prepare for 3.34.0 release Rubocop cleanup Update History.md Declare `Session#send_keys` (#2422) Minor rubocop updates Fix bug in Capybara::Node::Element#drop causing Pathname drops to be ignored Update History.md Support multiple labels when using allow_label_click on a checkbox - Issue #2421
As a [follow-up][] to [teamcapybara#2422][], expose the [document.activeElement][] (that is, the element with focus) via the `Session`. When called from Rack Test environments, `Session#active_element` raises an error. [Document.activeElement]: https://developer.mozilla.org/en-US/docs/Web/API/Document/activeElement [follow-up]: teamcapybara#2422 (comment) [teamcapybara#2422]: teamcapybara#2422 [document.activeElement]: https://developer.mozilla.org/en-US/docs/Web/API/Document/activeElement
As a [follow-up][] to [teamcapybara#2422][], expose the [document.activeElement][] (that is, the element with focus) via the `Session`. When called from Rack Test environments, `Session#active_element` raises an error. [Document.activeElement]: https://developer.mozilla.org/en-US/docs/Web/API/Document/activeElement [follow-up]: teamcapybara#2422 (comment) [teamcapybara#2422]: teamcapybara#2422 [document.activeElement]: https://developer.mozilla.org/en-US/docs/Web/API/Document/activeElement
As a [follow-up][] to [teamcapybara#2422][], expose the [document.activeElement][] (that is, the element with focus) via the `Session`. When called from Rack Test environments, `Session#active_element` raises an error. [Document.activeElement]: https://developer.mozilla.org/en-US/docs/Web/API/Document/activeElement [follow-up]: teamcapybara#2422 (comment) [teamcapybara#2422]: teamcapybara#2422 [document.activeElement]: https://developer.mozilla.org/en-US/docs/Web/API/Document/activeElement
As a [follow-up][] to [teamcapybara#2422][], expose the [document.activeElement][] (that is, the element with focus) via the `Session`. When called from Rack Test environments, `Session#active_element` raises an error. [Document.activeElement]: https://developer.mozilla.org/en-US/docs/Web/API/Document/activeElement [follow-up]: teamcapybara#2422 (comment) [teamcapybara#2422]: teamcapybara#2422 [document.activeElement]: https://developer.mozilla.org/en-US/docs/Web/API/Document/activeElement
When covering hotkeys and tab-navigation with test coverage, sending
keys via particular elements (via
Node#send_keys
) can be tedious.As an alternative, invoke
Session#send_keys
to delegate to the elementwith current focus. In most (all?) browsers,
document.activeElement
will return the
<body>
element when there are no elements with focus.In Selenium-enabled environments,
Session#send_keys
delegates to thecurrent element with focus (via document.activeElement). Treat
Session#send_keys
as a no-operation in Rack Test environments.