Best Capybara code snippet using Capybara.describe_expression_filters
selector.rb
Source:selector.rb
...54 (with.is_a?(Regexp) ? val =~ with : val == with.to_s).tap do |res|55 add_error("Expected value to be #{with.inspect} but was #{val.inspect}") unless res56 end57 end58 describe_expression_filters do |type: nil, **options|59 desc = +''60 (expression_filters.keys & options.keys).each { |ef| desc << " with #{ef} #{options[ef]}" }61 desc << " of type #{type.inspect}" if type62 desc63 end64 describe_node_filters do |**options|65 " with value #{options[:with].to_s.inspect}" if options.key?(:with)66 end67end68Capybara.add_selector(:fieldset, locator_type: [String, Symbol]) do69 xpath do |locator, legend: nil, **|70 locator_matchers = (XPath.attr(:id) == locator.to_s) | XPath.child(:legend)[XPath.string.n.is(locator.to_s)]71 locator_matchers |= XPath.attr(test_id) == locator.to_s if test_id72 xpath = XPath.descendant(:fieldset)[locator && locator_matchers]73 xpath = xpath[XPath.child(:legend)[XPath.string.n.is(legend)]] if legend74 xpath75 end76 node_filter(:disabled, :boolean) { |node, value| !(value ^ node.disabled?) }77end78Capybara.add_selector(:link, locator_type: [String, Symbol]) do79 xpath do |locator, href: true, alt: nil, title: nil, **|80 xpath = builder(XPath.descendant(:a)).add_attribute_conditions(href: href)81 unless locator.nil?82 locator = locator.to_s83 matchers = [XPath.attr(:id) == locator,84 XPath.string.n.is(locator),85 XPath.attr(:title).is(locator),86 XPath.descendant(:img)[XPath.attr(:alt).is(locator)]]87 matchers << XPath.attr(:'aria-label').is(locator) if enable_aria_label88 matchers << XPath.attr(test_id).equals(locator) if test_id89 xpath = xpath[matchers.reduce(:|)]90 end91 xpath = xpath[find_by_attr(:title, title)]92 xpath = xpath[XPath.descendant(:img)[XPath.attr(:alt) == alt]] if alt93 xpath94 end95 node_filter(:href) do |node, href|96 # If not a Regexp it's been handled in the main XPath97 (href.is_a?(Regexp) ? node[:href].match(href) : true).tap do |res|98 add_error "Expected href to match #{href.inspect} but it was #{node[:href].inspect}" unless res99 end100 end101 expression_filter(:download, valid_values: [true, false, String]) do |expr, download|102 builder(expr).add_attribute_conditions(download: download)103 end104 describe_expression_filters do |**options|105 desc = +''106 if (href = options[:href])107 desc << " with href #{'matching ' if href.is_a? Regexp}#{href.inspect}"108 elsif options.key?(:href) # is nil/false specified?109 desc << ' with no href attribute'110 end111 desc112 end113end114Capybara.add_selector(:button, locator_type: [String, Symbol]) do115 xpath(:value, :title, :type) do |locator, **options|116 input_btn_xpath = XPath.descendant(:input)[XPath.attr(:type).one_of('submit', 'reset', 'image', 'button')]117 btn_xpath = XPath.descendant(:button)118 image_btn_xpath = XPath.descendant(:input)[XPath.attr(:type) == 'image']119 unless locator.nil?120 locator = locator.to_s121 locator_matchers = XPath.attr(:id).equals(locator) | XPath.attr(:value).is(locator) | XPath.attr(:title).is(locator)122 locator_matchers |= XPath.attr(:'aria-label').is(locator) if enable_aria_label123 locator_matchers |= XPath.attr(test_id) == locator if test_id124 input_btn_xpath = input_btn_xpath[locator_matchers]125 btn_xpath = btn_xpath[locator_matchers | XPath.string.n.is(locator) | XPath.descendant(:img)[XPath.attr(:alt).is(locator)]]126 alt_matches = XPath.attr(:alt).is(locator)127 alt_matches |= XPath.attr(:'aria-label').is(locator) if enable_aria_label128 image_btn_xpath = image_btn_xpath[alt_matches]129 end130 %i[value title type].inject(input_btn_xpath.union(btn_xpath).union(image_btn_xpath)) do |memo, ef|131 memo[find_by_attr(ef, options[ef])]132 end133 end134 node_filter(:disabled, :boolean, default: false, skip_if: :all) { |node, value| !(value ^ node.disabled?) }135 describe_expression_filters136 describe_node_filters do |disabled: nil, **|137 ' that is disabled' if disabled == true138 end139end140Capybara.add_selector(:link_or_button, locator_type: [String, Symbol]) do141 label 'link or button'142 xpath do |locator, **options|143 self.class.all.values_at(:link, :button).map do |selector|144 instance_exec(locator, options, &selector.xpath)145 end.reduce(:union)146 end147 node_filter(:disabled, :boolean, default: false, skip_if: :all) { |node, value| node.tag_name == 'a' || !(value ^ node.disabled?) }148 describe_node_filters do |disabled: nil, **|149 ' that is disabled' if disabled == true150 end151end152Capybara.add_selector(:fillable_field, locator_type: [String, Symbol]) do153 label 'field'154 xpath do |locator, allow_self: nil, **options|155 xpath = XPath.axis(allow_self ? :"descendant-or-self" : :descendant, :input, :textarea)[156 !XPath.attr(:type).one_of('submit', 'image', 'radio', 'checkbox', 'hidden', 'file')157 ]158 locate_field(xpath, locator, options)159 end160 expression_filter(:type) do |expr, type|161 type = type.to_s162 if type == 'textarea'163 expr.self(type.to_sym)164 else165 expr[XPath.attr(:type) == type]166 end167 end168 filter_set(:_field, %i[disabled multiple name placeholder])169 node_filter(:with) do |node, with|170 val = node.value171 (with.is_a?(Regexp) ? val =~ with : val == with.to_s).tap do |res|172 add_error("Expected value to be #{with.inspect} but was #{val.inspect}") unless res173 end174 end175 describe_expression_filters176 describe_node_filters do |**options|177 " with value #{options[:with].to_s.inspect}" if options.key?(:with)178 end179end180Capybara.add_selector(:radio_button, locator_type: [String, Symbol]) do181 label 'radio button'182 xpath do |locator, allow_self: nil, **options|183 xpath = XPath.axis(allow_self ? :"descendant-or-self" : :descendant, :input)[184 XPath.attr(:type) == 'radio'185 ]186 locate_field(xpath, locator, options)187 end188 filter_set(:_field, %i[checked unchecked disabled name])189 node_filter(:option) do |node, value|190 val = node.value191 (val == value.to_s).tap do |res|192 add_error("Expected option value to be #{value.inspect} but it was #{val.inspect}") unless res193 end194 end195 describe_expression_filters196 describe_node_filters do |option: nil, **|197 " with value #{option.inspect}" if option198 end199end200Capybara.add_selector(:checkbox, locator_type: [String, Symbol]) do201 xpath do |locator, allow_self: nil, **options|202 xpath = XPath.axis(allow_self ? :"descendant-or-self" : :descendant, :input)[203 XPath.attr(:type) == 'checkbox'204 ]205 locate_field(xpath, locator, options)206 end207 filter_set(:_field, %i[checked unchecked disabled name])208 node_filter(:option) do |node, value|209 val = node.value210 (val == value.to_s).tap do |res|211 add_error("Expected option value to be #{value.inspect} but it was #{val.inspect}") unless res212 end213 end214 describe_expression_filters215 describe_node_filters do |option: nil, **|216 " with value #{option.inspect}" if option217 end218end219Capybara.add_selector(:select, locator_type: [String, Symbol]) do220 label 'select box'221 xpath do |locator, **options|222 xpath = XPath.descendant(:select)223 locate_field(xpath, locator, options)224 end225 filter_set(:_field, %i[disabled multiple name placeholder])226 node_filter(:options) do |node, options|227 actual = if node.visible?228 node.all(:xpath, './/option', wait: false).map(&:text)229 else230 node.all(:xpath, './/option', visible: false, wait: false).map { |option| option.text(:all) }231 end232 (options.sort == actual.sort).tap do |res|233 add_error("Expected options #{options.inspect} found #{actual.inspect}") unless res234 end235 end236 expression_filter(:with_options) do |expr, options|237 options.inject(expr) do |xpath, option|238 xpath[self.class.all[:option].call(option)]239 end240 end241 node_filter(:selected) do |node, selected|242 actual = node.all(:xpath, './/option', visible: false, wait: false).select(&:selected?).map { |option| option.text(:all) }243 (Array(selected).sort == actual.sort).tap do |res|244 add_error("Expected #{selected.inspect} to be selected found #{actual.inspect}") unless res245 end246 end247 node_filter(:with_selected) do |node, selected|248 actual = node.all(:xpath, './/option', visible: false, wait: false).select(&:selected?).map { |option| option.text(:all) }249 (Array(selected) - actual).empty?.tap do |res|250 add_error("Expected at least #{selected.inspect} to be selected found #{actual.inspect}") unless res251 end252 end253 describe_expression_filters do |with_options: nil, **opts|254 desc = +''255 desc << " with at least options #{with_options.inspect}" if with_options256 desc << describe_all_expression_filters(opts)257 desc258 end259 describe_node_filters do |options: nil, selected: nil, with_selected: nil, **|260 desc = +''261 desc << " with options #{options.inspect}" if options262 desc << " with #{selected.inspect} selected" if selected263 desc << " with at least #{with_selected.inspect} selected" if with_selected264 desc265 end266end267Capybara.add_selector(:datalist_input, locator_type: [String, Symbol]) do268 label 'input box with datalist completion'269 xpath do |locator, **options|270 xpath = XPath.descendant(:input)[XPath.attr(:list)]271 locate_field(xpath, locator, options)272 end273 filter_set(:_field, %i[disabled name placeholder])274 node_filter(:options) do |node, options|275 actual = node.find("//datalist[@id=#{node[:list]}]", visible: :all).all(:datalist_option, wait: false).map(&:value)276 (options.sort == actual.sort).tap do |res|277 add_error("Expected #{options.inspect} options found #{actual.inspect}") unless res278 end279 end280 expression_filter(:with_options) do |expr, options|281 options.inject(expr) do |xpath, option|282 xpath[XPath.attr(:list) == XPath.anywhere(:datalist)[self.class.all[:datalist_option].call(option)].attr(:id)]283 end284 end285 describe_expression_filters do |with_options: nil, **opts|286 desc = +''287 desc << " with at least options #{with_options.inspect}" if with_options288 desc << describe_all_expression_filters(opts)289 desc290 end291 describe_node_filters do |options: nil, **|292 " with options #{options.inspect}" if options293 end294end295Capybara.add_selector(:option, locator_type: [String, Symbol]) do296 xpath do |locator|297 xpath = XPath.descendant(:option)298 xpath = xpath[XPath.string.n.is(locator.to_s)] unless locator.nil?299 xpath300 end301 node_filter(:disabled, :boolean) { |node, value| !(value ^ node.disabled?) }302 node_filter(:selected, :boolean) { |node, value| !(value ^ node.selected?) }303 describe_node_filters do |**options|304 desc = +''305 desc << " that is#{' not' unless options[:disabled]} disabled" if options.key?(:disabled)306 desc << " that is#{' not' unless options[:selected]} selected" if options.key?(:selected)307 desc308 end309end310Capybara.add_selector(:datalist_option, locator_type: [String, Symbol]) do311 label 'datalist option'312 visible(:all)313 xpath do |locator|314 xpath = XPath.descendant(:option)315 xpath = xpath[XPath.string.n.is(locator.to_s) | (XPath.attr(:value) == locator.to_s)] unless locator.nil?316 xpath317 end318 node_filter(:disabled, :boolean) { |node, value| !(value ^ node.disabled?) }319 describe_node_filters do |**options|320 " that is#{' not' unless options[:disabled]} disabled" if options.key?(:disabled)321 end322end323Capybara.add_selector(:file_field, locator_type: [String, Symbol]) do324 label 'file field'325 xpath do |locator, allow_self: nil, **options|326 xpath = XPath.axis(allow_self ? :"descendant-or-self" : :descendant, :input)[327 XPath.attr(:type) == 'file'328 ]329 locate_field(xpath, locator, options)330 end331 filter_set(:_field, %i[disabled multiple name])332 describe_expression_filters333end334Capybara.add_selector(:label, locator_type: [String, Symbol]) do335 label 'label'336 xpath(:for) do |locator, options|337 xpath = XPath.descendant(:label)338 unless locator.nil?339 locator_matchers = XPath.string.n.is(locator.to_s) | (XPath.attr(:id) == locator.to_s)340 locator_matchers |= XPath.attr(test_id) == locator if test_id341 xpath = xpath[locator_matchers]342 end343 if options.key?(:for)344 if (for_option = options[:for].is_a?(Capybara::Node::Element) ? options[:for][:id] : options[:for])345 with_attr = XPath.attr(:for) == for_option.to_s346 labelable_elements = %i[button input keygen meter output progress select textarea]347 wrapped = !XPath.attr(:for) &348 XPath.descendant(*labelable_elements)[XPath.attr(:id) == for_option.to_s]349 xpath = xpath[with_attr | wrapped]350 end351 end352 xpath353 end354 node_filter(:for) do |node, field_or_value|355 # Non element values were handled through the expression filter356 next true unless field_or_value.is_a? Capybara::Node::Element357 if (for_val = node[:for])358 field_or_value[:id] == for_val359 else360 field_or_value.find_xpath('./ancestor::label[1]').include? node.base361 end362 end363 describe_expression_filters do |**options|364 " for element with id of \"#{options[:for]}\"" if options.key?(:for) && !options[:for].is_a?(Capybara::Node::Element)365 end366 describe_node_filters do |**options|367 " for element #{options[:for]}" if options[:for]&.is_a?(Capybara::Node::Element)368 end369end370Capybara.add_selector(:table, locator_type: [String, Symbol]) do371 xpath do |locator, caption: nil, **|372 xpath = XPath.descendant(:table)373 unless locator.nil?374 locator_matchers = (XPath.attr(:id) == locator.to_s) | XPath.descendant(:caption).is(locator.to_s)375 locator_matchers |= XPath.attr(test_id) == locator if test_id376 xpath = xpath[locator_matchers]377 end378 xpath = xpath[XPath.descendant(:caption) == caption] if caption379 xpath380 end381 expression_filter(:with_cols, valid_values: [Array]) do |xpath, cols|382 col_conditions = cols.map do |col|383 if col.is_a? Hash384 col.reduce(nil) do |xp, (header, cell)|385 header_xp = XPath.descendant(:th)[XPath.string.n.is(header)]386 cell_xp = XPath.descendant(:tr)[header_xp].descendant(:td)387 next cell_xp[XPath.string.n.is(cell)] unless xp388 table_ancestor = XPath.ancestor(:table)[1]389 xp = XPath::Expression.new(:join, table_ancestor, xp)390 cell_xp[XPath.string.n.is(cell) & XPath.position.equals(xp.preceding_sibling(:td).count.plus(1))]391 end392 else393 cells_xp = col.reduce(nil) do |xp, cell|394 cell_conditions = [XPath.string.n.is(cell)]395 if xp396 prev_row_xp = XPath::Expression.new(:join, XPath.ancestor(:tr)[1].preceding_sibling(:tr), xp)397 cell_conditions << XPath.position.equals(prev_row_xp.preceding_sibling(:td).count.plus(1))398 end399 XPath.descendant(:td)[cell_conditions.reduce :&]400 end401 XPath::Expression.new(:join, XPath.descendant(:tr), cells_xp)402 end403 end.reduce(:&)404 xpath[col_conditions]405 end406 expression_filter(:cols, valid_values: [Array]) do |xpath, cols|407 raise ArgumentError, ":cols must be an Array of Arrays" unless cols.all? { |col| col.is_a? Array }408 rows = cols.transpose409 xpath = xpath[XPath.descendant(:tbody).descendant(:tr).count.equals(rows.size) | (XPath.descendant(:tr).count.equals(rows.size) & ~XPath.descendant(:tbody))]410 col_conditions = rows.map do |row|411 row_conditions = row.map do |cell|412 XPath.self(:td)[XPath.string.n.is(cell)]413 end414 row_conditions = row_conditions.reverse.reduce do |cond, cell|415 cell[XPath.following_sibling[cond]]416 end417 row_xpath = XPath.descendant(:tr)[XPath.descendant(:td)[row_conditions]]418 row_xpath[XPath.descendant(:td).count.equals(row.size)]419 end.reduce(:&)420 xpath[col_conditions]421 end422 expression_filter(:with_rows, valid_values: [Array]) do |xpath, rows|423 rows_conditions = rows.map do |row|424 if row.is_a? Hash425 row_conditions = row.map do |header, cell|426 header_xp = XPath.ancestor(:table)[1].descendant(:tr)[1].descendant(:th)[XPath.string.n.is(header)]427 XPath.descendant(:td)[428 XPath.string.n.is(cell) & XPath.position.equals(header_xp.preceding_sibling.count.plus(1))429 ]430 end.reduce(:&)431 XPath.descendant(:tr)[row_conditions]432 else433 row_conditions = row.map do |cell|434 XPath.self(:td)[XPath.string.n.is(cell)]435 end436 row_conditions = row_conditions.reverse.reduce do |cond, cell|437 cell[XPath.following_sibling[cond]]438 end439 XPath.descendant(:tr)[XPath.descendant(:td)[row_conditions]]440 end441 end.reduce(:&)442 xpath[rows_conditions]443 end444 expression_filter(:rows, valid_values: [Array]) do |xpath, rows|445 xpath = xpath[XPath.descendant(:tbody).descendant(:tr).count.equals(rows.size) | (XPath.descendant(:tr).count.equals(rows.size) & ~XPath.descendant(:tbody))]446 rows_conditions = rows.map do |row|447 row_xpath = if row.is_a? Hash448 row_conditions = row.map do |header, cell|449 header_xp = XPath.ancestor(:table)[1].descendant(:tr)[1].descendant(:th)[XPath.string.n.is(header)]450 XPath.descendant(:td)[451 XPath.string.n.is(cell) & XPath.position.equals(header_xp.preceding_sibling.count.plus(1))452 ]453 end.reduce(:&)454 XPath.descendant(:tr)[row_conditions]455 else456 row_conditions = row.map do |cell|457 XPath.self(:td)[XPath.string.n.is(cell)]458 end459 row_conditions = row_conditions.reverse.reduce do |cond, cell|460 cell[XPath.following_sibling[cond]]461 end462 XPath.descendant(:tr)[XPath.descendant(:td)[row_conditions]]463 end464 row_xpath[XPath.descendant(:td).count.equals(row.size)]465 end.reduce(:&)466 xpath[rows_conditions]467 end468 describe_expression_filters do |caption: nil, **|469 " with caption \"#{caption}\"" if caption470 end471end472Capybara.add_selector(:table_row, locator_type: [Array, Hash]) do473 xpath do |locator|474 xpath = XPath.descendant(:tr)475 if locator.is_a? Hash476 locator.reduce(xpath) do |xp, (header, cell)|477 header_xp = XPath.ancestor(:table)[1].descendant(:tr)[1].descendant(:th)[XPath.string.n.is(header)]478 cell_xp = XPath.descendant(:td)[479 XPath.string.n.is(cell) & XPath.position.equals(header_xp.preceding_sibling.count.plus(1))480 ]481 xp[cell_xp]482 end483 else484 initial_td = XPath.descendant(:td)[XPath.string.n.is(locator.shift)]485 tds = locator.reverse.map { |cell| XPath.following_sibling(:td)[XPath.string.n.is(cell)] }.reduce { |xp, cell| xp[cell] }486 xpath[initial_td[tds]]487 end488 end489end490Capybara.add_selector(:frame, locator_type: [String, Symbol]) do491 xpath do |locator, name: nil, **|492 xpath = XPath.descendant(:iframe).union(XPath.descendant(:frame))493 unless locator.nil?494 locator_matchers = (XPath.attr(:id) == locator.to_s) | (XPath.attr(:name) == locator.to_s)495 locator_matchers |= XPath.attr(test_id) == locator if test_id496 xpath = xpath[locator_matchers]497 end498 xpath[find_by_attr(:name, name)]499 end500 describe_expression_filters do |name: nil, **|501 " with name #{name}" if name502 end503end504Capybara.add_selector(:element, locator_type: [String, Symbol]) do505 xpath do |locator, **|506 XPath.descendant.where(locator ? XPath.local_name == locator.to_s : nil)507 end508 expression_filter(:attributes, matcher: /.+/) do |xpath, name, val|509 builder(xpath).add_attribute_conditions(name => val)510 end511 node_filter(:attributes, matcher: /.+/) do |node, name, val|512 next true unless val.is_a?(Regexp)513 (node[name] =~ val).tap do |res|514 add_error("Expected #{name} to match #{val.inspect} but it was #{node[name]}") unless res515 end516 end517 describe_expression_filters do |**options|518 booleans, values = options.partition { |_k, v| [true, false].include? v }.map(&:to_h)519 desc = describe_all_expression_filters(values)520 desc + booleans.map do |k, v|521 v ? " with #{k} attribute" : "without #{k} attribute"522 end.join523 end524end525# rubocop:enable Metrics/BlockLength...
describe_expression_filters
Using AI Code Generation
1Capybara::Session.new(:selenium).describe_expression_filters2Capybara::Session.new(:selenium).visit('/')3Capybara::Session.new(:selenium).describe_expression_filters4Capybara::Session.new(:selenium).visit('/')
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!