Skip to content

Capybara::ExpectationNotMet: Item does not match the provided selector, with v2.0.21 #777

@jean-francois-labbe

Description

@jean-francois-labbe

Trying to update to turbo 2.0.21, When running system test, I'm facing this error on some visit:
Capybara::ExpectationNotMet: Item does not match the provided selector

Adding breakpoint before the visit root_path, and executing the visit root_path from the debug console I now see this stack trace:

  /Users/jeff/.local/share/mise/installs/ruby/3.4.8/lib/ruby/gems/3.4.0/gems/capybara-3.40.0/lib/capybara/node/matchers.rb:588:in 'block in Capybara::Node::Matchers#assert_matches_selector'
  /Users/jeff/.local/share/mise/installs/ruby/3.4.8/lib/ruby/gems/3.4.0/gems/capybara-3.40.0/lib/capybara/node/matchers.rb:878:in 'block in Capybara::Node::Matchers#_verify_match_result'
  /Users/jeff/.local/share/mise/installs/ruby/3.4.8/lib/ruby/gems/3.4.0/gems/capybara-3.40.0/lib/capybara/node/base.rb:84:in 'Capybara::Node::Base#synchronize'
  /Users/jeff/.local/share/mise/installs/ruby/3.4.8/lib/ruby/gems/3.4.0/gems/capybara-3.40.0/lib/capybara/node/matchers.rb:877:in 'Capybara::Node::Matchers#_verify_match_result'
  /Users/jeff/.local/share/mise/installs/ruby/3.4.8/lib/ruby/gems/3.4.0/gems/capybara-3.40.0/lib/capybara/node/matchers.rb:587:in 'Capybara::Node::Matchers#assert_matches_selector'
  /Users/jeff/.local/share/mise/installs/ruby/3.4.8/lib/ruby/gems/3.4.0/bundler/gems/turbo-rails-aa583bb3f4ca/lib/turbo/system_test_helper.rb:30:in 'block in Turbo::SystemTestHelper#connect_turbo_cable_stream_sources'
  /Users/jeff/.local/share/mise/installs/ruby/3.4.8/lib/ruby/gems/3.4.0/gems/capybara-3.40.0/lib/capybara/result.rb:48:in 'block in Capybara::Result#each'
  <internal:kernel>:168:in 'Kernel#loop'
  /Users/jeff/.local/share/mise/installs/ruby/3.4.8/lib/ruby/gems/3.4.0/gems/capybara-3.40.0/lib/capybara/result.rb:45:in 'Capybara::Result#each'
  /Users/jeff/.local/share/mise/installs/ruby/3.4.8/lib/ruby/gems/3.4.0/bundler/gems/turbo-rails-aa583bb3f4ca/lib/turbo/system_test_helper.rb:29:in 'Turbo::SystemTestHelper#connect_turbo_cable_stream_sources'
  /Users/jeff/.local/share/mise/installs/ruby/3.4.8/lib/ruby/gems/3.4.0/bundler/gems/turbo-rails-aa583bb3f4ca/lib/turbo/engine.rb:171:in 'block in ActionDispatch::SystemTestCase#visit'
  <internal:kernel>:91:in 'Kernel#tap'
  /Users/jeff/.local/share/mise/installs/ruby/3.4.8/lib/ruby/gems/3.4.0/bundler/gems/turbo-rails-aa583bb3f4ca/lib/turbo/engine.rb:171:in 'ActionDispatch::SystemTestCase#visit'
  (rdbg)//Users/jeff/Work/project/test/system/user_test.rb:1:in 'block in <class:UserTest>'

I've narrowed it down to this commit aa583bb
I don't understand why this change would result in this error.

Edit:

before the visible :all change all(:turbo_cable_stream_source, **options, connected: false, wait: 0) returned []

def connect_turbo_cable_stream_sources(**options, &block)
all(:turbo_cable_stream_source, **options, connected: false, wait: 0).each do |element|
element.assert_matches_selector(:turbo_cable_stream_source, **options, connected: true, &block)
end
end

Now with visible :all change all(:turbo_cable_stream_source, **options, connected: false, wait: 0) returns:

<turbo-cable-stream-source channel="Turbo::StreamsChannel" signed-stream-name="IloybGtPaTh2Ym05aWFTOUVaWEJoY25SdFpXNTBMek13TnprMk9EYzVNUTpvbmxpbmVfdXNlcnMi--d4d4b0bfe5d3955767ea26d79fc1123f5d138d45397c643e2806b22e63b3edda"></turbo-cable-stream-source>
<turbo-cable-stream-source channel="Turbo::StreamsChannel" signed-stream-name="IloybGtPaTh2Ym05aWFTOVZjMlZ5THpNMU1qRXpOVGswTnc6bG9nZ2VkX291dCI=--3fa1a0ba08f01e33998faefb7c10bd34d6e164f6e62e22dfcb34caf435c1d863"></turbo-cable-stream-source>
<turbo-cable-stream-source channel="Turbo::StreamsChannel" signed-stream-name="ImVzY2FsYXRpb25fYXNzaWdubWVudHNfZGFzaGJvYXJkX3JldmFtcF9ob3VzaW5nX3VuaXRfem9uZV82NzgyMzMwNTQi--17e12309524b4c85e28e79cdc7c01d60fab2a6142f85f58ea9d01e67926eae8e" connected=""></turbo-cable-stream-source>
<turbo-cable-stream-source channel="Turbo::StreamsChannel" signed-stream-name="ImVzY2FsYXRpb25fYXNzaWdubWVudHNfZGFzaGJvYXJkX3JldmFtcF9ob3VzaW5nX3VuaXRfem9uZV9tdWx0aV9yZXNpZGVudHNfNTAyNzYzODYi--f1a6383d45c84478f71daeff9d5deabaa107b85cb883aa3ffa40c26157d55542"></turbo-cable-stream-source>
<turbo-cable-stream-source channel="Turbo::StreamsChannel" signed-stream-name="ImVzY2FsYXRpb25fYXNzaWdubWVudHNfZGFzaGJvYXJkX3JldmFtcF9ob3VzaW5nX3VuaXRfem9uZV9zaW5nbGVfcmVzaWRlbnRfNzA5ODE2OTIyIg==--ff440592182ac7d880c605252edd12c9de416b565bd7d43a7cf618bc09e3392e" connected=""></turbo-cable-stream-source>
<turbo-cable-stream-source channel="Turbo::StreamsChannel" signed-stream-name="InNoYXJlZF9yZXNpZGVuY2Vfc2l0ZV9kYXNoYm9hcmRfY2hhbm5lbF80MDI0Mzc4NzFfZW4tVVMi--ebfcab71964a10fc6deafdf0d1f8d5335cc03b53a3db3da1889bdb5f30550cf5"></turbo-cable-stream-source>
<turbo-cable-stream-source channel="Turbo::StreamsChannel" signed-stream-name="InNub296ZV91cGRhdGVzIg==--3d81f36b6acb7ad08934332b8e0c5958a986cb6d2e3cf3f152901efaa37da2c7" connected=""></turbo-cable-stream-source>
<turbo-cable-stream-source channel="Turbo::StreamsChannel" signed-stream-name="InNub296ZV91cGRhdGVzIg==--3d81f36b6acb7ad08934332b8e0c5958a986cb6d2e3cf3f152901efaa37da2c7" connected=""></turbo-cable-stream-source>
<turbo-cable-stream-source channel="Turbo::StreamsChannel" signed-stream-name="InNub296ZV91cGRhdGVzIg==--3d81f36b6acb7ad08934332b8e0c5958a986cb6d2e3cf3f152901efaa37da2c7"></turbo-cable-stream-source>

I notice I have duplicate turbo-cable-stream-source (is this an issue ?)
The most import one is the last one which doesn't have the connected="" attribute.
This is the one raising eval error: Item does not match the provided selector

The Capybara :turbo_cable_stream_source selector has one expression_filter checking the :connected attribute and it expects it to be present.

expression_filter :connected do |xpath, value|
builder(xpath).add_attribute_conditions(connected: value)
end

The issue is that connected="" attribute is not present in my case.
Seems that there could be a race condition, where the javascript has not had time to add the connected="" attribute to all turbo-cable-stream-source
https://github.com/hotwired/turbo-rails/blob/main/app/javascript/turbo/cable_stream_source_element.js#L36

The expression_filter :connected can be updated to support this case:

    expression_filter :connected do |xpath, value|
      attr = XPath.attr(:connected)

      case value
      when true
        xpath.where(attr == 'true')
      when false
        xpath.where(attr != 'true')
      else
        xpath
      end
    end

This makes my test pass.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions