Class: Plushie::Test::Session

Inherits:
Object
  • Object
show all
Defined in:
lib/plushie/test/session.rb

Overview

Test session driving the Elm loop against a pooled renderer. Each test gets its own Session with isolated model state.

Interactions (click, type_text, toggle, etc.) are sent via the renderer's interact protocol; resulting events are fed through the app's update cycle so the model stays in sync.

See the Elixir SDK's mock renderer backend for reference.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(app_class, pool:, session_id:) ⇒ Session

Returns a new instance of Session.

Parameters:

  • app_class (Class)

    the app class (includes Plushie::App)

  • pool (SessionPool)
  • session_id (String)


22
23
24
25
26
27
28
29
30
31
# File 'lib/plushie/test/session.rb', line 22

def initialize(app_class, pool:, session_id:)
  @app = app_class.new
  @pool = pool
  @session_id = session_id
  @format = pool.format
  @model = nil
  @tree = nil
  @diagnostics = []
  init_app
end

Instance Attribute Details

#modelObject (readonly)

Returns current app model.

Returns:

  • (Object)

    current app model



17
18
19
# File 'lib/plushie/test/session.rb', line 17

def model
  @model
end

Instance Method Details

#click(selector) ⇒ Object

Click a button widget.

Parameters:

  • selector (String)

    "#id" or "text content"



37
38
39
# File 'lib/plushie/test/session.rb', line 37

def click(selector)
  interact("click", selector)
end

#element_text(element) ⇒ String?

Extract text content from an element hash. Checks content, label, value, placeholder in order.

Parameters:

  • element (Hash)

Returns:

  • (String, nil)


226
227
228
229
230
231
# File 'lib/plushie/test/session.rb', line 226

def element_text(element)
  return nil unless element

  props = element["props"] || element[:props] || {}
  props["content"] || props["label"] || props["value"] || props["placeholder"]
end

#find(selector) ⇒ Hash?

Find a widget by selector. Returns the node hash or nil.

Parameters:

  • selector (String)

    "#id" or "text content"

Returns:

  • (Hash, nil)


109
110
111
112
113
114
115
116
117
# File 'lib/plushie/test/session.rb', line 109

def find(selector)
  id = SecureRandom.hex(4)
  response = @pool.send_and_wait(
    {type: "query", id: id, target: "find", selector: build_selector(selector)},
    @session_id, :query_response
  )
  data = response[:data] || response["data"]
  (data.nil? || data.empty?) ? nil : data
end

#find!(selector) ⇒ Hash

Find a widget by selector. Raises with a helpful error if not found, including the current tree IDs and similar ID suggestions.

Parameters:

  • selector (String)

Returns:

  • (Hash)

Raises:



125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/plushie/test/session.rb', line 125

def find!(selector)
  result = find(selector)
  unless result
    all_ids = Tree.ids(@tree)
    target = selector.start_with?("#") ? selector[1..] : selector
    suggestions = find_similar_ids(target, all_ids)

    msg = "Widget not found: #{selector}\n"
    msg << "\n  Did you mean: #{suggestions.map { "##{_1}" }.join(", ")}\n" if suggestions.any?
    msg << "\n  Current tree IDs: #{all_ids.join(", ")}"
    raise Plushie::Error, msg
  end
  result
end

#get_diagnosticsArray<Event::System>

Returns and clears accumulated prop validation diagnostics.

Returns:



208
209
210
211
212
# File 'lib/plushie/test/session.rb', line 208

def get_diagnostics
  result = @diagnostics.dup
  @diagnostics.clear
  result
end

#move_to(x, y) ⇒ Object

Move cursor to coordinates.

Parameters:

  • x (Numeric)
  • y (Numeric)


100
101
102
# File 'lib/plushie/test/session.rb', line 100

def move_to(x, y)
  interact("move_to", nil, x: x, y: y)
end

#press(key) ⇒ Object

Press a key (key down).

Parameters:

  • key (String)

    key combo string, e.g. "ctrl+s", "Enter", "a"



81
82
83
# File 'lib/plushie/test/session.rb', line 81

def press(key)
  interact("press", nil, combo: key)
end

#register_effect_stub(kind, response) ⇒ Object

Register an effect stub with the renderer for this session.

Parameters:

  • kind (String)

    effect kind

  • response (Object)

    canned response



186
187
188
189
190
191
192
# File 'lib/plushie/test/session.rb', line 186

def register_effect_stub(kind, response)
  @pool.send_message(
    {type: "register_effect_stub", kind: kind.to_s, response: response},
    @session_id
  )
  @pool.read_message(@session_id, timeout: 5)
end

#release(key) ⇒ Object

Release a key (key up).

Parameters:

  • key (String)

    key combo string



87
88
89
# File 'lib/plushie/test/session.rb', line 87

def release(key)
  interact("release", nil, combo: key)
end

#resetObject

Reset the session to initial state.



176
177
178
179
180
# File 'lib/plushie/test/session.rb', line 176

def reset
  @model = nil
  @tree = nil
  init_app
end

#screenshot(name, width: 1024, height: 768) ⇒ Hash

Capture a screenshot.

Parameters:

  • name (String)
  • width (Integer) (defaults to: 1024)
  • height (Integer) (defaults to: 768)

Returns:

  • (Hash)


167
168
169
170
171
172
173
# File 'lib/plushie/test/session.rb', line 167

def screenshot(name, width: 1024, height: 768)
  id = SecureRandom.hex(4)
  @pool.send_and_wait(
    {type: "screenshot", id: id, name: name, width: width, height: height},
    @session_id, :screenshot_response
  )
end

#select(selector, value) ⇒ Object

Select a value from pick_list, combo_box, or radio.

Parameters:

  • selector (String)
  • value (String)


68
69
70
# File 'lib/plushie/test/session.rb', line 68

def select(selector, value)
  interact("select", selector, value: value)
end

#slide(selector, value) ⇒ Object

Slide a slider to a value.

Parameters:

  • selector (String)
  • value (Numeric)


75
76
77
# File 'lib/plushie/test/session.rb', line 75

def slide(selector, value)
  interact("slide", selector, value: value)
end

#stopObject

Stop the session and release the renderer session.



215
216
217
218
219
220
# File 'lib/plushie/test/session.rb', line 215

def stop
  @pool.unregister(@session_id)
rescue => e
  # Swallow errors during cleanup
  warn "plushie test: error during session cleanup: #{e.message}" if $DEBUG
end

#submit(selector) ⇒ Object

Submit a text_input (press Enter).

Parameters:

  • selector (String)


50
51
52
53
54
55
# File 'lib/plushie/test/session.rb', line 50

def submit(selector)
  # Read current value from local tree
  node = find_in_local_tree(selector)
  value = node_prop(node, "value") || ""
  interact("submit", selector, value: value)
end

#toggle(selector) ⇒ Object

Toggle a checkbox or toggler.

Parameters:

  • selector (String)


59
60
61
62
63
# File 'lib/plushie/test/session.rb', line 59

def toggle(selector)
  node = find_in_local_tree(selector)
  current = node_prop(node, "checked") || node_prop(node, "active") || false
  interact("toggle", selector, value: !current)
end

#treeHash

Get the full tree from the renderer.

Returns:

  • (Hash)


142
143
144
145
146
147
148
149
# File 'lib/plushie/test/session.rb', line 142

def tree
  id = SecureRandom.hex(4)
  response = @pool.send_and_wait(
    {type: "query", id: id, target: "tree", selector: {}},
    @session_id, :query_response
  )
  response[:data] || response["data"]
end

#tree_hash(name) ⇒ Hash

Capture a structural tree hash.

Parameters:

  • name (String)

Returns:

  • (Hash)


154
155
156
157
158
159
160
# File 'lib/plushie/test/session.rb', line 154

def tree_hash(name)
  id = SecureRandom.hex(4)
  @pool.send_and_wait(
    {type: "tree_hash", id: id, name: name},
    @session_id, :tree_hash_response
  )
end

#type_key(key) ⇒ Object

Type a key (press + release).

Parameters:

  • key (String)

    key combo string



93
94
95
# File 'lib/plushie/test/session.rb', line 93

def type_key(key)
  interact("type_key", nil, combo: key)
end

#type_text(selector, text) ⇒ Object

Type text into a text_input or text_editor.

Parameters:

  • selector (String)
  • text (String)


44
45
46
# File 'lib/plushie/test/session.rb', line 44

def type_text(selector, text)
  interact("type_text", selector, text: text)
end

#unregister_effect_stub(kind) ⇒ Object

Remove a previously registered effect stub.

Parameters:

  • kind (String)

    effect kind



197
198
199
200
201
202
203
# File 'lib/plushie/test/session.rb', line 197

def unregister_effect_stub(kind)
  @pool.send_message(
    {type: "unregister_effect_stub", kind: kind.to_s},
    @session_id
  )
  @pool.read_message(@session_id, timeout: 5)
end