Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 27 additions & 9 deletions internal/prompter/accessible_prompter_test.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
//go:build !windows
//go:build linux || darwin

package prompter_test

import (
"fmt"
"io"
"os"
"slices"
"strings"
"testing"
Expand All @@ -17,6 +18,7 @@ import (
"github.com/hinshun/vt10x"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/sys/unix"
)

// The following tests are broadly testing the accessible prompter, and NOT asserting
Expand All @@ -34,8 +36,6 @@ import (
// but doesn't mandate that prompts always look exactly the same.
func TestAccessiblePrompter(t *testing.T) {

beforePasswordSendTimeout := 100 * time.Millisecond

t.Run("Select", func(t *testing.T) {
console := newTestVirtualTerminal(t)
p := newTestAccessiblePrompter(t, console)
Expand Down Expand Up @@ -505,8 +505,8 @@ func TestAccessiblePrompter(t *testing.T) {
_, err := console.ExpectString("Enter password")
require.NoError(t, err)

// Wait to ensure huh has time to set the echo mode
time.Sleep(beforePasswordSendTimeout)
// Wait until huh has disabled echo mode on the TTY
require.NoError(t, waitForEchoDisabled(console.Tty(), 5*time.Second))

// Enter a number
_, err = console.SendLine(dummyPassword)
Expand Down Expand Up @@ -596,8 +596,8 @@ func TestAccessiblePrompter(t *testing.T) {
_, err := console.ExpectString("Paste your authentication token:")
require.NoError(t, err)

// Wait to ensure huh has time to set the echo mode
time.Sleep(beforePasswordSendTimeout)
// Wait until huh has disabled echo mode on the TTY
require.NoError(t, waitForEchoDisabled(console.Tty(), 5*time.Second))

// Enter some dummy auth token
_, err = console.SendLine(dummyAuthToken)
Expand Down Expand Up @@ -641,8 +641,8 @@ func TestAccessiblePrompter(t *testing.T) {
_, err = console.ExpectString("Paste your authentication token:")
require.NoError(t, err)

// Wait to ensure huh has time to set the echo mode
time.Sleep(beforePasswordSendTimeout)
// Wait until huh has disabled echo mode on the TTY
require.NoError(t, waitForEchoDisabled(console.Tty(), 5*time.Second))

// Now enter some dummy auth token to return control back to the test
_, err = console.SendLine(dummyAuthTokenForAfterFailure)
Expand Down Expand Up @@ -956,3 +956,21 @@ func testCloser(t *testing.T, closer io.Closer) {
t.Errorf("Close failed: %s", err)
}
}

// waitForEchoDisabled polls the TTY until echo mode is disabled or the
// timeout is reached. This is used in password and auth token tests to
// ensure that huh has configured the terminal before we send input.
func waitForEchoDisabled(tty *os.File, timeout time.Duration) error {
deadline := time.Now().Add(timeout)
for time.Now().Before(deadline) {
termios, err := unix.IoctlGetTermios(int(tty.Fd()), ioctlGetTermios)
if err != nil {
return fmt.Errorf("getting terminal attributes: %w", err)
}
if termios.Lflag&unix.ECHO == 0 {
Comment thread
pdostal marked this conversation as resolved.
return nil
}
time.Sleep(time.Millisecond)
}
return fmt.Errorf("timed out waiting for echo mode to be disabled")
}
7 changes: 7 additions & 0 deletions internal/prompter/echo_darwin_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
//go:build darwin

package prompter_test

import "golang.org/x/sys/unix"

const ioctlGetTermios = unix.TIOCGETA
Comment thread
pdostal marked this conversation as resolved.
7 changes: 7 additions & 0 deletions internal/prompter/echo_linux_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
//go:build linux

package prompter_test

import "golang.org/x/sys/unix"

const ioctlGetTermios = unix.TCGETS
Comment thread
pdostal marked this conversation as resolved.
Loading