Skip to content

Add custom buttons to UserInput prompts - #1348

Open
CraigBurden wants to merge 1 commit into
google:masterfrom
CraigBurden:feature-prompt-buttons
Open

CraigBurden wants to merge 1 commit into
google:masterfrom
CraigBurden:feature-prompt-buttons

Conversation

@CraigBurden

Copy link
Copy Markdown

Add custom buttons to UserInput prompts

Motivation

Many operator prompts are really a choice: Pass / Fail, Retest / Stop, Accept / Reject. At the moment the only options are an Okay button or a text box, so tests either ask the operator to type a word or chain several yes/no prompts together. This PR lets a prompt offer its own buttons and reports which one was pressed. It works with or without a text box, so a single prompt can ask for a serial number and a verdict.

image
@htf.plug(prompts=user_input.UserInput)
def inspect_widget(test, prompts):
  test.measurements.widget_looks_ok = prompts.prompt(
      'Does the widget look OK?',
      buttons=[
          user_input.Button('Looks good', color='blue', value='pass'),
          user_input.Button('Damaged', color='red', value='fail'),
      ]).button == 'pass'

# Text and a button together:
response = prompts.prompt('Scan the serial, then choose:', text_input=True,
                          buttons=[user_input.Button('Accept'),
                                   user_input.Button('Reject', color='red')])
response.text, response.button  # ('SN123', 'Reject')

Changes

  • user_input.Button(text, color='grey', text_color=None, value=None): color is one of the GUI's built-in blue/red/grey styles or any CSS color. value is the button's response, and defaults to text.
  • prompt() / start_prompt() take a keyword-only buttons argument. A prompt with buttons returns PromptResponse(text, button), a NamedTuple. text is '' when text_input is false. Prompts without buttons still return str, so existing callers are unaffected.
  • respond(prompt_id, response, button=None): for a button prompt, button must match one of the buttons' responses, otherwise the response is ignored with a warning. Without buttons, behaviour is unchanged.
  • Web GUI: htf-user-input-plug shows the buttons in place of Okay/Submit. Clicking a button sends [id, text, button value]. With buttons, Enter in the text box doesn't submit, because a button still has to be chosen. dist/ is rebuilt with npm run build.
  • Console: the operator enters any text first, then the buttons are listed by number. They can type the number, the button text or its value, and invalid input re-prompts.
  • _asdict() gains a buttons list (text, value, color, text-color), using the same hyphenated key style as text-input and image-url.
  • examples/all_the_things.py gets an inspect_widget phase that shows the feature.

Testing

  • New cases in test/plugs/user_input_test.py:
    • the buttons entries in _asdict()
    • a blocking button prompt returning PromptResponse
    • text and a button together
    • responses ignored when the button is missing or matches none of the buttons
    • console input resolution
  • Full suite passes: pytest test (589 passed).
  • Manual GUI check with headless Chrome against a running StationServer:
    • built-in and custom colors render, and Okay is hidden while buttons are shown
    • clicking Fail (value='fail-value') returns PromptResponse('', 'fail-value')
    • text plus buttons: Enter leaves the prompt open, and clicking Reject returns PromptResponse('SN123', 'Reject')
    • a following prompt without buttons still shows Okay and returns ''
  • Console checked in a pty: SN9, then maybe (re-prompts), then 2 returns PromptResponse('SN9', 'rej').

🤖 Generated with Claude Code

prompt() and start_prompt() take an optional `buttons` list of Button
objects. The web GUI shows them in place of the Okay/Submit button.
Buttons use the built-in blue/red/grey styles or any CSS color, with an
optional label color.

A prompt with buttons returns a PromptResponse(text, button): the text
entered (empty unless text_input is set) and the value of the button
pressed (its text unless a value is given). Prompts without buttons
still return a string, so existing callers are unaffected.

respond() takes the pressed button as an optional third argument and
ignores responses to a button prompt that match none of its buttons. On
the console the user enters any text first, then picks a button by its
number, text or value.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant