func (caps Capabilities) WithShouldUseCompactResponses(b bool) Capabilities {
	caps["shouldUseCompactResponses"] = b
	return caps
}
WithShouldUseCompactResponses If set to YES will use compact (standards-compliant) & faster responses
Defaults to `true`
package gwda
import (
	"bytes"
	"context"
	"encoding/base64"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net"
	"net/http"
	"reflect"
	"regexp"
	"strconv"
	"strings"
	"time"
)
var HTTPClient = http.DefaultClient
var (
	DefaultWaitTimeout  = 60 * time.Second
	DefaultWaitInterval = 400 * time.Millisecond
	DefaultKeepAliveInterval = 30 * time.Second
)
func newRequest(method string, url string, rawBody []byte) (request *http.Request, err error) {
	var header = map[string]string{
		"Content-Type": "application/json;charset=UTF-8",
		"Accept":       "application/json",
	}
	if request, err = http.NewRequest(method, url, bytes.NewBuffer(rawBody)); err != nil {
		return nil, err
	}
	for k, v := range header {
		request.Header.Set(k, v)
	}
	return
}
func executeHTTP(wd *remoteWD, method string, rawURL string, rawBody []byte, usbHTTPClient ...*http.Client) (rawResp rawResponse, err error) {
	debugLog(fmt.Sprintf("--> %s %s\n%s", method, rawURL, rawBody))
	var req *http.Request
	if req, err = newRequest(method, rawURL, rawBody); err != nil {
		return
	}
	tmpHTTPClient := HTTPClient
	if len(usbHTTPClient) != 0 {
		tmpHTTPClient = usbHTTPClient[0]
		wd.UsbLock.Lock()
		defer wd.UsbLock.Unlock()
	}
	tmpHTTPClient.Timeout = 0
	start := time.Now()
	var resp *http.Response
	if resp, err = tmpHTTPClient.Do(req); err != nil {
		return nil, err
	}
	defer func() {
		_, _ = io.Copy(ioutil.Discard, resp.Body)
		_ = resp.Body.Close()
	}()
	rawResp, err = ioutil.ReadAll(resp.Body)
	debugLog(fmt.Sprintf("<-- %s %s %d %s\n%s\n", method, rawURL, resp.StatusCode, time.Since(start), rawResp))
	if err != nil {
		return nil, err
	}
	if err = rawResp.checkErr(); err != nil {
		if resp.StatusCode == http.StatusOK {
			return rawResp, nil
		}
		return nil, err
	}
	return
}
func keepAlive(d WebDriver) {
	go func() {
		if DefaultKeepAliveInterval <= 0 {
			return
		}
		ticker := time.NewTicker(DefaultKeepAliveInterval)
		for {
			select {
			case <-ticker.C:
				if _, err := d.Status(); err != nil {
					ticker.Stop()
					return
				}
			}
		}
	}()
}
var debugFlag = false
func SetDebug(debug bool) {
	debugFlag = debug
}
func debugLog(msg string) {
	if !debugFlag {
		return
	}
	log.Println("[GWDA-DEBUG] " + msg)
}
func convertToHTTPClient(_conn net.Conn) *http.Client {
	return &http.Client{
		Transport: &http.Transport{
			DialContext: func(_ context.Context, _, _ string) (net.Conn, error) {
				return _conn, nil
			},
		},
		Timeout: 0,
	}
}
type rawResponse []byte
func (r rawResponse) checkErr() (err error) {
	var reply = new(struct {
		Value struct {
			Err       string `json:"error"`
			Message   string `json:"message"`
			Traceback string `json:"traceback"`
		}
	})
	if err = json.Unmarshal(r, reply); err != nil {
		return err
	}
	if reply.Value.Err != "" {
		errText := reply.Value.Message
		re := regexp.MustCompile(`{.+?=(.+?)}`)
		if re.MatchString(reply.Value.Message) {
			subMatch := re.FindStringSubmatch(reply.Value.Message)
			errText = subMatch[len(subMatch)-1]
		}
		return fmt.Errorf("%s: %s", reply.Value.Err, errText)
	}
	return
}
func (r rawResponse) valueConvertToString() (s string, err error) {
	var reply = new(struct{ Value string })
	if err = json.Unmarshal(r, reply); err != nil {
		return "", err
	}
	s = reply.Value
	return
}
func (r rawResponse) valueConvertToBool() (b bool, err error) {
	var reply = new(struct{ Value bool })
	if err = json.Unmarshal(r, reply); err != nil {
		return false, err
	}
	b = reply.Value
	return
}
func (r rawResponse) valueConvertToSessionInfo() (sessionInfo SessionInfo, err error) {
	var reply = new(struct{ Value struct{ SessionInfo } })
	if err = json.Unmarshal(r, reply); err != nil {
		return SessionInfo{}, err
	}
	sessionInfo = reply.Value.SessionInfo
	return
}
func (r rawResponse) valueConvertToJsonRawMessage() (raw json.RawMessage, err error) {
	var reply = new(struct{ Value json.RawMessage })
	if err = json.Unmarshal(r, reply); err != nil {
		return nil, err
	}
	raw = reply.Value
	return
}
func (r rawResponse) valueDecodeAsBase64() (raw *bytes.Buffer, err error) {
	var str string
	if str, err = r.valueConvertToString(); err != nil {
		return nil, err
	}
	var decodeString []byte
	if decodeString, err = base64.StdEncoding.DecodeString(str); err != nil {
		return nil, err
	}
	raw = bytes.NewBuffer(decodeString)
	return
}
var errNoSuchElement = errors.New("no such element")
func (r rawResponse) valueConvertToElementID() (id string, err error) {
	var reply = new(struct{ Value map[string]string })
	if err = json.Unmarshal(r, reply); err != nil {
		return "", err
	}
	if len(reply.Value) == 0 {
		return "", errNoSuchElement
	}
	if id = elementIDFromValue(reply.Value); id == "" {
		return "", fmt.Errorf("invalid element returned: %+v", reply)
	}
	return
}
func (r rawResponse) valueConvertToElementIDs() (IDs []string, err error) {
	var reply = new(struct{ Value []map[string]string })
	if err = json.Unmarshal(r, reply); err != nil {
		return nil, err
	}
	if len(reply.Value) == 0 {
		return nil, errNoSuchElement
	}
	IDs = make([]string, len(reply.Value))
	for i, elem := range reply.Value {
		var id string
		if id = elementIDFromValue(elem); id == "" {
			return nil, fmt.Errorf("invalid element returned: %+v", reply)
		}
		IDs[i] = id
	}
	return
}
type AlertAction string
const (
	AlertActionAccept  AlertAction = "accept"
	AlertActionDismiss AlertAction = "dismiss"
)
type Capabilities map[string]interface{}
func NewCapabilities() Capabilities {
	return make(Capabilities)
}
func (caps Capabilities) WithAppLaunchOption(launchOpt AppLaunchOption) Capabilities {
	for k, v := range launchOpt {
		caps[k] = v
	}
	return caps
}
func (caps Capabilities) WithDefaultAlertAction(alertAction AlertAction) Capabilities {
	caps["defaultAlertAction"] = alertAction
	return caps
}
func (caps Capabilities) WithMaxTypingFrequency(n int) Capabilities {
	if n <= 0 {
		n = 60
	}
	caps["maxTypingFrequency"] = n
	return caps
}
func (caps Capabilities) WithWaitForIdleTimeout(second float64) Capabilities {
	caps["waitForIdleTimeout"] = second
	return caps
}
func (caps Capabilities) WithShouldUseTestManagerForVisibilityDetection(b bool) Capabilities {
	caps["shouldUseTestManagerForVisibilityDetection"] = b
	return caps
}