summaryrefslogtreecommitdiff
path: root/vendor/github.com/playwright-community/playwright-go/helpers.go
diff options
context:
space:
mode:
authormo khan <mo@mokhan.ca>2025-05-12 16:33:27 -0600
committermo khan <mo@mokhan.ca>2025-05-12 16:33:27 -0600
commit29b59441a4bbada64d8d07bd2609f15dfde670e5 (patch)
tree3b3583edb261279cfcdfd9eed904d118c4bf67b1 /vendor/github.com/playwright-community/playwright-go/helpers.go
parent78ccd9a4312eab7e11da4413733a12953f88a4fe (diff)
test: remove UI tests
Diffstat (limited to 'vendor/github.com/playwright-community/playwright-go/helpers.go')
-rw-r--r--vendor/github.com/playwright-community/playwright-go/helpers.go628
1 files changed, 0 insertions, 628 deletions
diff --git a/vendor/github.com/playwright-community/playwright-go/helpers.go b/vendor/github.com/playwright-community/playwright-go/helpers.go
deleted file mode 100644
index b2244f1..0000000
--- a/vendor/github.com/playwright-community/playwright-go/helpers.go
+++ /dev/null
@@ -1,628 +0,0 @@
-package playwright
-
-import (
- "errors"
- "fmt"
- "reflect"
- "regexp"
- "strings"
- "sync"
- "sync/atomic"
-
- mapset "github.com/deckarep/golang-set/v2"
-)
-
-type (
- routeHandler = func(Route)
-)
-
-func skipFieldSerialization(val reflect.Value) bool {
- typ := val.Type()
- return (typ.Kind() == reflect.Ptr ||
- typ.Kind() == reflect.Interface ||
- typ.Kind() == reflect.Map ||
- typ.Kind() == reflect.Slice) && val.IsNil() || (val.Kind() == reflect.Interface && val.Elem().Kind() == reflect.Ptr && val.Elem().IsNil())
-}
-
-func transformStructValues(in interface{}) interface{} {
- v := reflect.ValueOf(in)
- if v.Kind() == reflect.Ptr {
- v = v.Elem()
- }
- if _, ok := in.(*channel); ok {
- return in
- }
- if v.Kind() == reflect.Map || v.Kind() == reflect.Struct {
- return transformStructIntoMapIfNeeded(in)
- }
- if v.Kind() == reflect.Slice {
- outSlice := []interface{}{}
- for i := 0; i < v.Len(); i++ {
- if !skipFieldSerialization(v.Index(i)) {
- outSlice = append(outSlice, transformStructValues(v.Index(i).Interface()))
- }
- }
- return outSlice
- }
- if v.Interface() == Null() || (v.Kind() == reflect.String && v.String() == Null().(string)) {
- return "null"
- }
- return in
-}
-
-func transformStructIntoMapIfNeeded(inStruct interface{}) map[string]interface{} {
- out := make(map[string]interface{})
- v := reflect.ValueOf(inStruct)
- if v.Kind() == reflect.Ptr {
- v = v.Elem()
- }
- typ := v.Type()
- if v.Kind() == reflect.Struct {
- // Merge into the base map by the JSON struct tag
- for i := 0; i < v.NumField(); i++ {
- fi := typ.Field(i)
- // Skip the values when the field is a pointer (like *string) and nil.
- if fi.IsExported() && !skipFieldSerialization(v.Field(i)) {
- // We use the JSON struct fields for getting the original names
- // out of the field.
- tagv := fi.Tag.Get("json")
- key := strings.Split(tagv, ",")[0]
- if key == "" {
- key = fi.Name
- }
- out[key] = transformStructValues(v.Field(i).Interface())
- }
- }
- } else if v.Kind() == reflect.Map {
- // Merge into the base map
- for _, key := range v.MapKeys() {
- if !skipFieldSerialization(v.MapIndex(key)) {
- out[key.String()] = transformStructValues(v.MapIndex(key).Interface())
- }
- }
- }
- return out
-}
-
-// transformOptions handles the parameter data transformation
-func transformOptions(options ...interface{}) map[string]interface{} {
- var base map[string]interface{}
- var option interface{}
- // Case 1: No options are given
- if len(options) == 0 {
- return make(map[string]interface{})
- }
- if len(options) == 1 {
- // Case 2: a single value (either struct or map) is given.
- base = make(map[string]interface{})
- option = options[0]
- } else if len(options) == 2 {
- // Case 3: two values are given. The first one needs to be transformed
- // to a map, the sencond one will be then get merged into the first
- // base map.
- if reflect.ValueOf(options[0]).Kind() != reflect.Map {
- base = transformOptions(options[0])
- } else {
- base = transformStructIntoMapIfNeeded(options[0])
- }
- option = options[1]
- }
- v := reflect.ValueOf(option)
- if v.Kind() == reflect.Slice {
- if v.Len() == 0 {
- return base
- }
- option = v.Index(0).Interface()
- }
-
- if option == nil {
- return base
- }
- v = reflect.ValueOf(option)
-
- if v.Kind() == reflect.Ptr {
- v = v.Elem()
- }
-
- optionMap := transformStructIntoMapIfNeeded(v.Interface())
- for key, value := range optionMap {
- base[key] = value
- }
- return base
-}
-
-func remapValue(inMapValue reflect.Value, outStructValue reflect.Value) {
- switch outStructValue.Type().Kind() {
- case reflect.Bool:
- outStructValue.SetBool(inMapValue.Bool())
- case reflect.String:
- outStructValue.SetString(inMapValue.String())
- case reflect.Float64:
- outStructValue.SetFloat(inMapValue.Float())
- case reflect.Int:
- outStructValue.SetInt(int64(inMapValue.Float()))
- case reflect.Slice:
- outStructValue.Set(reflect.MakeSlice(outStructValue.Type(), inMapValue.Len(), inMapValue.Cap()))
- for i := 0; i < inMapValue.Len(); i++ {
- remapValue(inMapValue.Index(i).Elem(), outStructValue.Index(i))
- }
- case reflect.Struct:
- structTyp := outStructValue.Type()
- for i := 0; i < outStructValue.NumField(); i++ {
- fi := structTyp.Field(i)
- key := strings.Split(fi.Tag.Get("json"), ",")[0]
- structField := outStructValue.Field(i)
- structFieldDeref := outStructValue.Field(i)
- if structField.Type().Kind() == reflect.Ptr {
- structField.Set(reflect.New(structField.Type().Elem()))
- structFieldDeref = structField.Elem()
- }
- for _, e := range inMapValue.MapKeys() {
- if key == e.String() {
- value := inMapValue.MapIndex(e)
- remapValue(value.Elem(), structFieldDeref)
- }
- }
- }
- default:
- panic(inMapValue.Interface())
- }
-}
-
-func remapMapToStruct(inputMap interface{}, outStruct interface{}) {
- remapValue(reflect.ValueOf(inputMap), reflect.ValueOf(outStruct).Elem())
-}
-
-type urlMatcher struct {
- raw interface{}
- pattern *regexp.Regexp
- matchFn func(url string) bool
-}
-
-func newURLMatcher(urlOrPredicate interface{}, baseURL *string, isWsUrl ...bool) *urlMatcher {
- switch v := urlOrPredicate.(type) {
- case *regexp.Regexp:
- return &urlMatcher{pattern: v, raw: urlOrPredicate}
- case string:
- return &urlMatcher{
- pattern: resolveGlobToRegex(baseURL, v, len(isWsUrl) > 0 && isWsUrl[0]),
- raw: urlOrPredicate,
- }
- }
- fn, ok := urlOrPredicate.(func(string) bool)
- if ok {
- return &urlMatcher{
- matchFn: fn,
- raw: urlOrPredicate,
- }
- }
- panic(fmt.Errorf("invalid urlOrPredicate: %v", urlOrPredicate))
-}
-
-func (u *urlMatcher) Matches(url string) bool {
- if u.matchFn != nil {
- return u.matchFn(url)
- }
- if u.pattern != nil {
- return u.pattern.MatchString(url)
- }
- return false
-}
-
-// SameWith compares String() if urlOrPredicate is *regexp.Regexp
-func (u *urlMatcher) SameWith(urlOrPredicate interface{}) bool {
- switch v := urlOrPredicate.(type) {
- case *regexp.Regexp:
- return u.pattern.String() == v.String()
- default:
- return u.raw == urlOrPredicate
- }
-}
-
-type routeHandlerInvocation struct {
- route Route
- complete chan bool
-}
-
-type routeHandlerEntry struct {
- matcher *urlMatcher
- handler routeHandler
- times int
- count int32
- ignoreErrors *atomic.Bool
- activeInvocations mapset.Set[*routeHandlerInvocation]
-}
-
-func (r *routeHandlerEntry) Matches(url string) bool {
- return r.matcher.Matches(url)
-}
-
-func (r *routeHandlerEntry) Handle(route Route) chan bool {
- handlerInvocation := &routeHandlerInvocation{
- route: route,
- complete: make(chan bool, 1),
- }
- r.activeInvocations.Add(handlerInvocation)
-
- defer func() {
- handlerInvocation.complete <- true
- r.activeInvocations.Remove(handlerInvocation)
- }()
- defer func() {
- // If the handler was stopped (without waiting for completion), we ignore all exceptions.
- if r.ignoreErrors.Load() {
- _ = recover()
- route.(*routeImpl).reportHandled(false)
- } else {
- e := recover()
- if e != nil {
- err, ok := e.(error)
- if ok && errors.Is(err, ErrTargetClosed) {
- panic(fmt.Errorf("\"%w\" while running route callback.\nConsider awaiting `page.UnrouteAll(playwright.PageUnrouteAllOptions{Behavior: playwright.UnrouteBehaviorIgnoreErrors})`\nbefore the end of the test to ignore remaining routes in flight.", err))
- }
- panic(e)
- }
- }
- }()
-
- return r.handleInternal(route)
-}
-
-func (r *routeHandlerEntry) Stop(behavior string) {
- // When a handler is manually unrouted or its page/context is closed we either
- // - wait for the current handler invocations to finish
- // - or do not wait, if the user opted out of it, but swallow all exceptions
- // that happen after the unroute/close.
- if behavior == string(*UnrouteBehaviorIgnoreErrors) {
- r.ignoreErrors.Store(true)
- } else {
- wg := &sync.WaitGroup{}
- r.activeInvocations.Each(func(activation *routeHandlerInvocation) bool {
- if !activation.route.(*routeImpl).didThrow {
- wg.Add(1)
- go func(complete chan bool) {
- <-complete
- wg.Done()
- }(activation.complete)
- }
- return false
- })
- wg.Wait()
- }
-}
-
-func (r *routeHandlerEntry) handleInternal(route Route) chan bool {
- handled := route.(*routeImpl).startHandling()
- atomic.AddInt32(&r.count, 1)
- r.handler(route)
- return handled
-}
-
-func (r *routeHandlerEntry) WillExceed() bool {
- if r.times == 0 {
- return false
- }
- return int(atomic.LoadInt32(&r.count)+1) >= r.times
-}
-
-func newRouteHandlerEntry(matcher *urlMatcher, handler routeHandler, times ...int) *routeHandlerEntry {
- n := 0
- if len(times) > 0 {
- n = times[0]
- }
- return &routeHandlerEntry{
- matcher: matcher,
- handler: handler,
- times: n,
- count: 0,
- ignoreErrors: &atomic.Bool{},
- activeInvocations: mapset.NewSet[*routeHandlerInvocation](),
- }
-}
-
-func prepareInterceptionPatterns(handlers []*routeHandlerEntry) []map[string]interface{} {
- patterns := []map[string]interface{}{}
- all := false
- for _, h := range handlers {
- switch h.matcher.raw.(type) {
- case *regexp.Regexp:
- pattern, flags := convertRegexp(h.matcher.raw.(*regexp.Regexp))
- patterns = append(patterns, map[string]interface{}{
- "regexSource": pattern,
- "regexFlags": flags,
- })
- case string:
- patterns = append(patterns, map[string]interface{}{
- "glob": h.matcher.raw.(string),
- })
- default:
- all = true
- }
- }
- if all {
- return []map[string]interface{}{
- {
- "glob": "**/*",
- },
- }
- }
- return patterns
-}
-
-const defaultTimeout = 30 * 1000
-
-type timeoutSettings struct {
- sync.RWMutex
- parent *timeoutSettings
- defaultTimeout *float64
- defaultNavigationTimeout *float64
-}
-
-func (t *timeoutSettings) SetDefaultTimeout(timeout *float64) {
- t.Lock()
- defer t.Unlock()
- t.defaultTimeout = timeout
-}
-
-func (t *timeoutSettings) DefaultTimeout() *float64 {
- t.RLock()
- defer t.RUnlock()
- return t.defaultTimeout
-}
-
-func (t *timeoutSettings) Timeout(timeout ...float64) float64 {
- t.RLock()
- defer t.RUnlock()
- if len(timeout) == 1 {
- return timeout[0]
- }
- if t.defaultTimeout != nil {
- return *t.defaultTimeout
- }
- if t.parent != nil {
- return t.parent.Timeout()
- }
- return defaultTimeout
-}
-
-func (t *timeoutSettings) DefaultNavigationTimeout() *float64 {
- t.RLock()
- defer t.RUnlock()
- return t.defaultNavigationTimeout
-}
-
-func (t *timeoutSettings) SetDefaultNavigationTimeout(navigationTimeout *float64) {
- t.Lock()
- defer t.Unlock()
- t.defaultNavigationTimeout = navigationTimeout
-}
-
-func (t *timeoutSettings) NavigationTimeout() float64 {
- t.RLock()
- defer t.RUnlock()
- if t.defaultNavigationTimeout != nil {
- return *t.defaultNavigationTimeout
- }
- if t.parent != nil {
- return t.parent.NavigationTimeout()
- }
- return defaultTimeout
-}
-
-func newTimeoutSettings(parent *timeoutSettings) *timeoutSettings {
- return &timeoutSettings{
- parent: parent,
- defaultTimeout: nil,
- defaultNavigationTimeout: nil,
- }
-}
-
-// SelectOptionValues is the option struct for ElementHandle.Select() etc.
-type SelectOptionValues struct {
- ValuesOrLabels *[]string
- Values *[]string
- Indexes *[]int
- Labels *[]string
- Elements *[]ElementHandle
-}
-
-func convertSelectOptionSet(values SelectOptionValues) map[string]interface{} {
- out := make(map[string]interface{})
- if values == (SelectOptionValues{}) {
- return out
- }
-
- var o []map[string]interface{}
- if values.ValuesOrLabels != nil {
- for _, v := range *values.ValuesOrLabels {
- m := map[string]interface{}{"valueOrLabel": v}
- o = append(o, m)
- }
- }
- if values.Values != nil {
- for _, v := range *values.Values {
- m := map[string]interface{}{"value": v}
- o = append(o, m)
- }
- }
- if values.Indexes != nil {
- for _, i := range *values.Indexes {
- m := map[string]interface{}{"index": i}
- o = append(o, m)
- }
- }
- if values.Labels != nil {
- for _, l := range *values.Labels {
- m := map[string]interface{}{"label": l}
- o = append(o, m)
- }
- }
- if o != nil {
- out["options"] = o
- }
-
- var e []*channel
- if values.Elements != nil {
- for _, eh := range *values.Elements {
- e = append(e, eh.(*elementHandleImpl).channel)
- }
- }
- if e != nil {
- out["elements"] = e
- }
-
- return out
-}
-
-func unroute(inRoutes []*routeHandlerEntry, url interface{}, handlers ...routeHandler) ([]*routeHandlerEntry, []*routeHandlerEntry, error) {
- var handler routeHandler
- if len(handlers) == 1 {
- handler = handlers[0]
- }
- handlerPtr := reflect.ValueOf(handler).Pointer()
-
- removed := make([]*routeHandlerEntry, 0)
- remaining := make([]*routeHandlerEntry, 0)
-
- for _, route := range inRoutes {
- routeHandlerPtr := reflect.ValueOf(route.handler).Pointer()
- // note: compare regex expression if url is a regexp, not pointer
- if !route.matcher.SameWith(url) ||
- (handler != nil && routeHandlerPtr != handlerPtr) {
- remaining = append(remaining, route)
- } else {
- removed = append(removed, route)
- }
- }
-
- return removed, remaining, nil
-}
-
-func serializeMapToNameAndValue(headers map[string]string) []map[string]string {
- serialized := make([]map[string]string, 0)
- for name, value := range headers {
- serialized = append(serialized, map[string]string{
- "name": name,
- "value": value,
- })
- }
- return serialized
-}
-
-// assignStructFields assigns fields from src to dest,
-//
-// omitExtra determines whether to omit src's extra fields
-func assignStructFields(dest, src interface{}, omitExtra bool) error {
- destValue := reflect.ValueOf(dest)
- if destValue.Kind() != reflect.Ptr || destValue.IsNil() {
- return fmt.Errorf("dest must be a non-nil pointer")
- }
- destValue = destValue.Elem()
- if destValue.Kind() != reflect.Struct {
- return fmt.Errorf("dest must be a struct")
- }
-
- srcValue := reflect.ValueOf(src)
- if srcValue.Kind() == reflect.Ptr {
- srcValue = srcValue.Elem()
- }
- if srcValue.Kind() != reflect.Struct {
- return fmt.Errorf("src must be a struct")
- }
-
- for i := 0; i < destValue.NumField(); i++ {
- destField := destValue.Field(i)
- destFieldType := destField.Type()
- destFieldName := destValue.Type().Field(i).Name
-
- if srcField := srcValue.FieldByName(destFieldName); srcField.IsValid() && srcField.Type() != destFieldType {
- return fmt.Errorf("mismatched field type for field %s", destFieldName)
- } else if srcField.IsValid() {
- destField.Set(srcField)
- }
- }
-
- if !omitExtra {
- for i := 0; i < srcValue.NumField(); i++ {
- srcFieldName := srcValue.Type().Field(i).Name
-
- if destField := destValue.FieldByName(srcFieldName); !destField.IsValid() {
- return fmt.Errorf("extra field %s in src", srcFieldName)
- }
- }
- }
-
- return nil
-}
-
-func deserializeNameAndValueToMap(headersArray []map[string]string) map[string]string {
- unserialized := make(map[string]string)
- for _, item := range headersArray {
- unserialized[item["name"]] = item["value"]
- }
- return unserialized
-}
-
-type recordHarOptions struct {
- Path string `json:"path"`
- Content *HarContentPolicy `json:"content,omitempty"`
- Mode *HarMode `json:"mode,omitempty"`
- UrlGlob *string `json:"urlGlob,omitempty"`
- UrlRegexSource *string `json:"urlRegexSource,omitempty"`
- UrlRegexFlags *string `json:"urlRegexFlags,omitempty"`
-}
-
-type recordHarInputOptions struct {
- Path string
- URL interface{}
- Mode *HarMode
- Content *HarContentPolicy
- OmitContent *bool
-}
-
-type harRecordingMetadata struct {
- Path string
- Content *HarContentPolicy
-}
-
-func prepareRecordHarOptions(option recordHarInputOptions) recordHarOptions {
- out := recordHarOptions{
- Path: option.Path,
- }
- if option.URL != nil {
- switch option.URL.(type) {
- case *regexp.Regexp:
- pattern, flags := convertRegexp(option.URL.(*regexp.Regexp))
- out.UrlRegexSource = String(pattern)
- out.UrlRegexFlags = String(flags)
- case string:
- out.UrlGlob = String(option.URL.(string))
- }
- }
- if option.Mode != nil {
- out.Mode = option.Mode
- }
- if option.Content != nil {
- out.Content = option.Content
- } else if option.OmitContent != nil && *option.OmitContent {
- out.Content = HarContentPolicyOmit
- }
- return out
-}
-
-type safeValue[T any] struct {
- sync.Mutex
- v T
-}
-
-func (s *safeValue[T]) Set(v T) {
- s.Lock()
- defer s.Unlock()
- s.v = v
-}
-
-func (s *safeValue[T]) Get() T {
- s.Lock()
- defer s.Unlock()
- return s.v
-}