waitForSearch returns an interactionStep that blocks until the field's current async search completes. It wires a one-shot callback into the field's onSearchDone hook and waits for it to fire, avoiding fixed-duration sleeps that are too short on slow architectures such as s390x under QEMU. The wait
(t *testing.T, field *multiSelectSearchField)
| 120 | // The wait is bounded by the test's deadline (from -timeout) so a hung search |
| 121 | // fails the test with a clear message rather than blocking the whole test run. |
| 122 | func waitForSearch(t *testing.T, field *multiSelectSearchField) interactionStep { |
| 123 | t.Helper() |
| 124 | done := make(chan struct{}) |
| 125 | var once sync.Once |
| 126 | field.onSearchDone.Store(func() { |
| 127 | once.Do(func() { close(done) }) |
| 128 | }) |
| 129 | |
| 130 | var timeout <-chan time.Time |
| 131 | if deadline, ok := t.Deadline(); ok { |
| 132 | timeout = time.After(time.Until(deadline)) |
| 133 | } else { |
| 134 | timeout = time.After(30 * time.Second) |
| 135 | } |
| 136 | |
| 137 | return interactionStep{ |
| 138 | waitFn: func() { |
| 139 | select { |
| 140 | case <-done: |
| 141 | case <-timeout: |
| 142 | t.Fatal("timed out waiting for async search to complete") |
| 143 | } |
| 144 | }, |
| 145 | } |
| 146 | } |
| 147 | |
| 148 | // --- Test harness --- |
| 149 |
no test coverage detected