diff options
Diffstat (limited to 'vendor/github.com/playwright-community/playwright-go/waiter.go')
| -rw-r--r-- | vendor/github.com/playwright-community/playwright-go/waiter.go | 181 |
1 files changed, 0 insertions, 181 deletions
diff --git a/vendor/github.com/playwright-community/playwright-go/waiter.go b/vendor/github.com/playwright-community/playwright-go/waiter.go deleted file mode 100644 index fbcb39f..0000000 --- a/vendor/github.com/playwright-community/playwright-go/waiter.go +++ /dev/null @@ -1,181 +0,0 @@ -package playwright - -import ( - "context" - "fmt" - "reflect" - "sync" - "sync/atomic" - "time" -) - -type ( - waiter struct { - mu sync.Mutex - timeout float64 - fulfilled atomic.Bool - listeners []eventListener - errChan chan error - waitFunc func() (interface{}, error) - } - eventListener struct { - emitter EventEmitter - event string - handler interface{} - } -) - -// RejectOnEvent sets the Waiter to return an error when an event occurs (and the predicate returns true) -func (w *waiter) RejectOnEvent(emitter EventEmitter, event string, err error, predicates ...interface{}) *waiter { - w.mu.Lock() - defer w.mu.Unlock() - if w.waitFunc != nil { - w.reject(fmt.Errorf("waiter: call RejectOnEvent before WaitForEvent")) - return w - } - handler := func(ev ...interface{}) { - if w.fulfilled.Load() { - return - } - if len(predicates) == 0 { - w.reject(err) - } else { - result := reflect.ValueOf(predicates[0]).Call([]reflect.Value{reflect.ValueOf(ev[0])}) - if result[0].Bool() { - w.reject(err) - } - } - } - emitter.On(event, handler) - w.listeners = append(w.listeners, eventListener{ - emitter: emitter, - event: event, - handler: handler, - }) - return w -} - -// WithTimeout sets timeout, in milliseconds, for the waiter. 0 means no timeout. -func (w *waiter) WithTimeout(timeout float64) *waiter { - w.mu.Lock() - defer w.mu.Unlock() - if w.waitFunc != nil { - w.reject(fmt.Errorf("waiter: please set timeout before WaitForEvent")) - return w - } - w.timeout = timeout - return w -} - -// WaitForEvent sets the Waiter to return when an event occurs (and the predicate returns true) -func (w *waiter) WaitForEvent(emitter EventEmitter, event string, predicate interface{}) *waiter { - w.mu.Lock() - defer w.mu.Unlock() - if w.waitFunc != nil { - w.reject(fmt.Errorf("waiter: WaitForEvent can only be called once")) - return w - } - evChan := make(chan interface{}, 1) - handler := w.createHandler(evChan, predicate) - ctx, cancel := context.WithCancel(context.Background()) - if w.timeout != 0 { - timeout := w.timeout - go func() { - select { - case <-time.After(time.Duration(timeout) * time.Millisecond): - err := fmt.Errorf("%w:Timeout %.2fms exceeded.", ErrTimeout, timeout) - w.reject(err) - return - case <-ctx.Done(): - return - } - }() - } - - emitter.On(event, handler) - w.listeners = append(w.listeners, eventListener{ - emitter: emitter, - event: event, - handler: handler, - }) - - w.waitFunc = func() (interface{}, error) { - var ( - err error - val interface{} - ) - select { - case err = <-w.errChan: - break - case val = <-evChan: - break - } - cancel() - w.mu.Lock() - defer w.mu.Unlock() - for _, l := range w.listeners { - l.emitter.RemoveListener(l.event, l.handler) - } - close(evChan) - if err != nil { - return nil, err - } - return val, nil - } - return w -} - -// Wait waits for the waiter to return. It needs to call WaitForEvent once first. -func (w *waiter) Wait() (interface{}, error) { - if w.waitFunc == nil { - return nil, fmt.Errorf("waiter: call WaitForEvent first") - } - return w.waitFunc() -} - -// RunAndWait waits for the waiter to return after calls func. -func (w *waiter) RunAndWait(cb func() error) (interface{}, error) { - if w.waitFunc == nil { - return nil, fmt.Errorf("waiter: call WaitForEvent first") - } - if cb != nil { - if err := cb(); err != nil { - w.errChan <- err - } - } - return w.waitFunc() -} - -func (w *waiter) createHandler(evChan chan<- interface{}, predicate interface{}) func(...interface{}) { - return func(ev ...interface{}) { - if w.fulfilled.Load() { - return - } - if predicate == nil || reflect.ValueOf(predicate).IsNil() { - w.fulfilled.Store(true) - if len(ev) == 1 { - evChan <- ev[0] - } else { - evChan <- nil - } - } else { - result := reflect.ValueOf(predicate).Call([]reflect.Value{reflect.ValueOf(ev[0])}) - if result[0].Bool() { - w.fulfilled.Store(true) - evChan <- ev[0] - } - } - } -} - -func (w *waiter) reject(err error) { - w.fulfilled.Store(true) - w.errChan <- err -} - -func newWaiter() *waiter { - w := &waiter{ - errChan: make(chan error, 1), - } - return w -} |
