File: node.rb

package info (click to toggle)
ruby-poltergeist 1.18.1-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, buster
  • size: 368 kB
  • sloc: ruby: 1,528; makefile: 3
file content (207 lines) | stat: -rw-r--r-- 4,670 bytes parent folder | download
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
# frozen_string_literal: true

module Capybara::Poltergeist
  class Node < Capybara::Driver::Node
    attr_reader :page_id, :id

    def initialize(driver, page_id, id)
      super(driver, self)

      @page_id = page_id
      @id      = id
    end

    def browser
      driver.browser
    end

    def command(name, *args)
      browser.send(name, page_id, id, *args)
    rescue BrowserError => error
      case error.name
      when 'Poltergeist.ObsoleteNode'
        raise ObsoleteNode.new(self, error.response)
      when 'Poltergeist.MouseEventFailed'
        raise MouseEventFailed.new(self, error.response)
      else
        raise
      end
    end

    def parents
      command(:parents).map { |parent_id| self.class.new(driver, page_id, parent_id) }
    end

    def find(method, selector)
      command(:find_within, method, selector).map { |id| self.class.new(driver, page_id, id) }
    end

    def find_xpath(selector)
      find :xpath, selector
    end

    def find_css(selector)
      find :css, selector
    end

    def all_text
      filter_text command(:all_text)
    end

    def visible_text
      if Capybara::VERSION.to_f < 3.0
        filter_text command(:visible_text)
      else
        command(:visible_text).to_s
                              .gsub(/\A[[:space:]&&[^\u00a0]]+/, "")
                              .gsub(/[[:space:]&&[^\u00a0]]+\z/, "")
                              .gsub(/\n+/, "\n")
                              .tr("\u00a0", ' ')
      end
    end

    def property(name)
      command :property, name
    end

    def [](name)
      # Although the attribute matters, the property is consistent. Return that in
      # preference to the attribute for links and images.
      if (tag_name == 'img' and name == 'src') or (tag_name == 'a' and name == 'href' )
         #if attribute exists get the property
         value = command(:attribute, name) && command(:property, name)
         return value
      end

      value = property(name)
      value = command(:attribute, name) if value.nil? || value.is_a?(Hash)

      value
    end

    def attributes
      command :attributes
    end

    def value
      command :value
    end

    def set(value, options = {})
      warn "Options passed to Node#set but Poltergeist doesn't currently support any - ignoring" unless options.empty?

      if tag_name == 'input'
        case self[:type]
        when 'radio'
          click
        when 'checkbox'
          click if value != checked?
        when 'file'
          files = value.respond_to?(:to_ary) ? value.to_ary.map(&:to_s) : value.to_s
          command :select_file, files
        else
          command :set, value.to_s
        end
      elsif tag_name == 'textarea'
        command :set, value.to_s
      elsif self[:isContentEditable]
        command :delete_text
        send_keys(value.to_s)
      end
    end

    def select_option
      command :select, true
    end

    def unselect_option
      command(:select, false) or
      raise(Capybara::UnselectNotAllowed, "Cannot unselect option from single select box.")
    end

    def tag_name
      @tag_name ||= command(:tag_name)
    end

    def visible?
      command :visible?
    end

    def checked?
      self[:checked]
    end

    def selected?
      !!self[:selected]
    end

    def disabled?
      command :disabled?
    end

    def click(keys=[], offset={})
      command :click, keys, offset
    end

    def right_click(keys=[], offset={})
      command :right_click, keys, offset
    end

    def double_click(keys=[], offset={})
      command :double_click, keys, offset
    end

    def hover
      command :hover
    end

    def drag_to(other)
      command :drag, other.id
    end

    def drag_by(x, y)
      command :drag_by, x, y
    end

    def trigger(event)
      command :trigger, event
    end

    def ==(other)
      (page_id == other.page_id) && command(:equals, other.id)
    end

    def send_keys(*keys)
      command :send_keys, keys
    end
    alias_method :send_key, :send_keys

    def path
      command :path
    end

    # @api private
    def to_json(*)
      JSON.generate as_json
    end

    # @api private
    def as_json(*)
      { ELEMENT: {page_id: @page_id, id: @id} }
    end

    private

    def filter_text(text, visible = true)
      if Capybara::VERSION.to_f < 3
        Capybara::Helpers.normalize_whitespace(text.to_s)
      else
        text.gsub(/[\u200b\u200e\u200f]/, '')
            .gsub(/[\ \n\f\t\v\u2028\u2029]+/, ' ')
            .gsub(/\A[[:space:]&&[^\u00a0]]+/, "")
            .gsub(/[[:space:]&&[^\u00a0]]+\z/, "")
            .tr("\u00a0", ' ')
      end
    end
  end
end