@@ -5,6 +5,7 @@ package prompter_test
55import (
66 "fmt"
77 "io"
8+ "os"
89 "slices"
910 "strings"
1011 "testing"
@@ -17,6 +18,7 @@ import (
1718 "github.com/hinshun/vt10x"
1819 "github.com/stretchr/testify/assert"
1920 "github.com/stretchr/testify/require"
21+ "golang.org/x/sys/unix"
2022)
2123
2224// The following tests are broadly testing the accessible prompter, and NOT asserting
@@ -34,8 +36,6 @@ import (
3436// but doesn't mandate that prompts always look exactly the same.
3537func TestAccessiblePrompter (t * testing.T ) {
3638
37- beforePasswordSendTimeout := 100 * time .Millisecond
38-
3939 t .Run ("Select" , func (t * testing.T ) {
4040 console := newTestVirtualTerminal (t )
4141 p := newTestAccessiblePrompter (t , console )
@@ -505,8 +505,8 @@ func TestAccessiblePrompter(t *testing.T) {
505505 _ , err := console .ExpectString ("Enter password" )
506506 require .NoError (t , err )
507507
508- // Wait to ensure huh has time to set the echo mode
509- time . Sleep ( beforePasswordSendTimeout )
508+ // Wait until huh has disabled echo mode on the TTY
509+ waitForEchoDisabled ( t , console . Tty (), 5 * time . Second )
510510
511511 // Enter a number
512512 _ , err = console .SendLine (dummyPassword )
@@ -596,8 +596,8 @@ func TestAccessiblePrompter(t *testing.T) {
596596 _ , err := console .ExpectString ("Paste your authentication token:" )
597597 require .NoError (t , err )
598598
599- // Wait to ensure huh has time to set the echo mode
600- time . Sleep ( beforePasswordSendTimeout )
599+ // Wait until huh has disabled echo mode on the TTY
600+ waitForEchoDisabled ( t , console . Tty (), 5 * time . Second )
601601
602602 // Enter some dummy auth token
603603 _ , err = console .SendLine (dummyAuthToken )
@@ -641,8 +641,8 @@ func TestAccessiblePrompter(t *testing.T) {
641641 _ , err = console .ExpectString ("Paste your authentication token:" )
642642 require .NoError (t , err )
643643
644- // Wait to ensure huh has time to set the echo mode
645- time . Sleep ( beforePasswordSendTimeout )
644+ // Wait until huh has disabled echo mode on the TTY
645+ waitForEchoDisabled ( t , console . Tty (), 5 * time . Second )
646646
647647 // Now enter some dummy auth token to return control back to the test
648648 _ , err = console .SendLine (dummyAuthTokenForAfterFailure )
@@ -956,3 +956,20 @@ func testCloser(t *testing.T, closer io.Closer) {
956956 t .Errorf ("Close failed: %s" , err )
957957 }
958958}
959+
960+ // waitForEchoDisabled polls the TTY until echo mode is disabled or the
961+ // timeout is reached. This is used in password and auth token tests to
962+ // ensure that huh has configured the terminal before we send input.
963+ func waitForEchoDisabled (t * testing.T , tty * os.File , timeout time.Duration ) {
964+ t .Helper ()
965+ deadline := time .Now ().Add (timeout )
966+ for time .Now ().Before (deadline ) {
967+ termios , err := unix .IoctlGetTermios (int (tty .Fd ()), ioctlGetTermios )
968+ require .NoError (t , err )
969+ if termios .Lflag & unix .ECHO == 0 {
970+ return
971+ }
972+ time .Sleep (time .Millisecond )
973+ }
974+ t .Fatal ("timed out waiting for echo mode to be disabled" )
975+ }
0 commit comments