File: select.rb

package info (click to toggle)
ruby-capybara 3.40.0%2Bds-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,368 kB
  • sloc: ruby: 23,988; javascript: 752; makefile: 11
file content (81 lines) | stat: -rw-r--r-- 2,790 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# frozen_string_literal: true

Capybara.add_selector(:select, locator_type: [String, Symbol]) do
  label 'select box'

  xpath do |locator, **options|
    xpath = XPath.descendant(:select)
    locate_field(xpath, locator, **options)
  end

  filter_set(:_field, %i[disabled multiple name placeholder])

  node_filter(:options) do |node, options|
    actual = options_text(node)
    (options.sort == actual.sort).tap do |res|
      add_error("Expected options #{options.inspect} found #{actual.inspect}") unless res
    end
  end

  node_filter(:enabled_options) do |node, options|
    actual = options_text(node) { |o| !o.disabled? }
    (options.sort == actual.sort).tap do |res|
      add_error("Expected enabled options #{options.inspect} found #{actual.inspect}") unless res
    end
  end

  node_filter(:disabled_options) do |node, options|
    actual = options_text(node, &:disabled?)
    (options.sort == actual.sort).tap do |res|
      add_error("Expected disabled options #{options.inspect} found #{actual.inspect}") unless res
    end
  end

  expression_filter(:with_options) do |expr, options|
    options.inject(expr) do |xpath, option|
      xpath.where(expression_for(:option, option))
    end
  end

  node_filter(:selected) do |node, selected|
    actual = options_text(node, visible: false, &:selected?)
    (Array(selected).sort == actual.sort).tap do |res|
      add_error("Expected #{selected.inspect} to be selected found #{actual.inspect}") unless res
    end
  end

  node_filter(:with_selected) do |node, selected|
    actual = options_text(node, visible: false, &:selected?)
    (Array(selected) - actual).empty?.tap do |res|
      add_error("Expected at least #{selected.inspect} to be selected found #{actual.inspect}") unless res
    end
  end

  describe_expression_filters do |with_options: nil, **|
    desc = +''
    desc << " with at least options #{with_options.inspect}" if with_options
    desc
  end

  describe_node_filters do |
    options: nil, disabled_options: nil, enabled_options: nil,
    selected: nil, with_selected: nil,
    disabled: nil, **|
    desc = +''
    desc << " with options #{options.inspect}" if options
    desc << " with disabled options #{disabled_options.inspect}}" if disabled_options
    desc << " with enabled options #{enabled_options.inspect}" if enabled_options
    desc << " with #{selected.inspect} selected" if selected
    desc << " with at least #{with_selected.inspect} selected" if with_selected
    desc << ' which is disabled' if disabled
    desc
  end

  def options_text(node, **opts, &filter_block)
    opts[:wait] = false
    opts[:visible] = false unless node.visible?
    node.all(:xpath, './/option', **opts, &filter_block).map do |o|
      o.text((:all if opts[:visible] == false))
    end
  end
end