{"record":{"id":"f7c702ef2b969dea","repo":"teamcapybara/capybara","slug":"res-join-or","errorCode":null,"errorMessage":"res.join(' or ')","messagePattern":"res\\.join\\(' or '\\)","errorType":"exception","errorClass":"Capybara::ExpectationNotMet","httpStatus":null,"severity":"error","filePath":"lib/capybara/node/matchers.rb","lineNumber":211,"sourceCode":"      # It accepts all options that {Capybara::Node::Finders#all} accepts,\n      # such as `:text` and `:visible`.\n      #\n      # The `:wait` option applies to all of the selectors as a group, so any of the locators must be present\n      # within `:wait` (defaults to {Capybara.configure default_max_wait_time}) seconds.\n      #\n      # @overload assert_any_of_selectors([kind = Capybara.default_selector], *locators, **options)\n      #\n      def assert_any_of_selectors(*args, wait: nil, **options, &optional_filter_block)\n        wait = session_options.default_max_wait_time if wait.nil?\n        selector = extract_selector(args)\n        synchronize(wait) do\n          res = args.map do |locator|\n            assert_selector(selector, locator, options, &optional_filter_block)\n            break nil\n          rescue Capybara::ExpectationNotMet => e\n            e.message\n          end\n          raise Capybara::ExpectationNotMet, res.join(' or ') if res\n\n          true\n        end\n      end\n\n      ##\n      #\n      # Asserts that a given selector is not on the page or a descendant of the current node.\n      # Usage is identical to {#assert_selector}.\n      #\n      # Query options such as `:count`, `:minimum`, `:maximum`, and `:between` are\n      # considered to be an integral part of the selector. This will return\n      # `true`, for example, if a page contains 4 anchors but the query expects 5:\n      #\n      #     page.assert_no_selector('a', minimum: 1) # Found, raises Capybara::ExpectationNotMet\n      #     page.assert_no_selector('a', count: 4)   # Found, raises Capybara::ExpectationNotMet\n      #     page.assert_no_selector('a', count: 5)   # Not Found, returns true\n      #","sourceCodeStart":193,"sourceCodeEnd":229,"githubUrl":"https://github.com/teamcapybara/capybara/blob/15b5fdb76e972e9623d5af2123ed3755594f9732/lib/capybara/node/matchers.rb#L193-L229","documentation":"assert_any_of_selectors raises ExpectationNotMet only when every supplied locator failed: it maps each locator through assert_selector, collecting each Capybara::ExpectationNotMet message, and short-circuits (break nil) on the first success. The final message is the per-locator failure messages joined with ' or ', so you see exactly why each alternative did not match.","triggerScenarios":"page.assert_any_of_selectors(:css, '#error', '#warning', '#notice') when none of the three exist after the wait; asserting either of two button texts ('Save', 'Submit') when the app renders 'Apply'; passing a selector kind explicitly then locators that all fail filters like visible: true.","commonSituations":"Apps with versioned/branched UI where either of two labels may render, A/B-tested copy in tests, refactor where both old and new markup were expected but the page shows neither (navigation failed, wrong page loaded), typo in one of the alternatives making the whole chain fail.","solutions":["Read the joined message: each segment is a full assert_selector failure explaining that alternative's mismatch","Fix the wrong locators or add the actually-rendered alternative ('Apply') to the list","Verify you are on the page that can render any alternative (assert current_path or a page-level marker first)","Extend wait if the alternatives appear asynchronously: assert_any_of_selectors(:css, '#a', '#b', wait: 5)"],"exampleFix":"# before\npage.assert_any_of_selectors(:field, 'Email', 'E-mail address')\n\n# after\npage.assert_any_of_selectors(:field, 'Email', 'E-mail address', 'Email address', wait: 5)","handlingStrategy":"retry","validationCode":"present = %w[#error #warning #notice].any? { |sel| page.has_selector?(sel, wait: 5) }\npage.assert_any_of_selectors(:css, '#error', '#warning', '#notice') if present","typeGuard":null,"tryCatchPattern":"begin\n  page.assert_any_of_selectors(:css, '#a', '#b', wait: 5)\nrescue Capybara::ExpectationNotMet => e\n  save_and_open_page # none of the alternatives matched — inspect DOM\n  raise\nend","preventionTips":["Keep the alternative list curated when UI copy changes","Assert page identity (current_path or header) before any-of assertions","Prefer data-test attributes over visible text alternatives"],"tags":["capybara","assertion","any-of","selector","expectation-not-met"],"backgroundTag":"multi-selector-none-matched","analyzedSha":"15b5fdb76e972e9623d5af2123ed3755594f9732","analyzedAt":"2026-08-21T16:53:45.588Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}