in go/webdriver/webdriver.go [199:294]
func CreateSession(ctx context.Context, addr string, attempts int, requestedCaps *capabilities.Capabilities) (WebDriver, error) {
reqBody := requestedCaps.ToMixedMode()
urlPrefix, err := url.Parse(addr)
if err != nil {
return nil, errors.New(compName, err)
}
urlSuffix, err := url.Parse("session/")
if err != nil {
return nil, errors.New(compName, err)
}
fullURL := urlPrefix.ResolveReference(urlSuffix)
c, err := command(fullURL, "")
if err != nil {
return nil, err
}
client := &http.Client{}
for ; attempts > 0; attempts-- {
d, err := func() (*webDriver, error) {
respBody, err := post(ctx, client, c, reqBody, nil)
if err != nil {
return nil, err
}
val, ok := respBody.Value.(map[string]interface{})
if !ok {
return nil, errors.New(compName, fmt.Errorf("value field must be an object in %+v", respBody))
}
var caps map[string]interface{}
session := respBody.SessionID
if session != "" {
// OSS protocol puts Session ID at the top level:
// {
// "value": { capabilities object },
// "sessionId": "id",
// "status": 0
// }
caps = val
} else {
// W3C protocol wraps everything in a "value" key:
// {
// "value": {
// "capabilities": { capabilities object },
// "sessionId": "id"
// }
// }
session, _ = val["sessionId"].(string)
if session == "" {
return nil, errors.New(compName, fmt.Errorf("no session id specified in %+v", respBody))
}
caps, ok = val["capabilities"].(map[string]interface{})
if !ok {
return nil, errors.New(compName, fmt.Errorf("no capabilities in value of %+v", respBody))
}
}
sessionURL, err := url.Parse(session + "/")
if err != nil {
return nil, errors.New(compName, err)
}
d := &webDriver{
address: fullURL.ResolveReference(sessionURL),
sessionID: session,
capabilities: caps,
client: client,
scriptTimeout: scriptTimeout(requestedCaps),
w3c: respBody.Status == nil,
}
if err := d.Healthy(ctx); err != nil {
if err := d.Quit(ctx); err != nil {
log.Printf("error quitting WebDriver session: %v", err)
}
return nil, err
}
return d, nil
}()
if err == nil {
return d, nil
}
if errors.IsPermanent(err) || attempts <= 1 {
return nil, err
}
}
// This should only occur if called with attempts <= 0
return nil, errors.New(compName, fmt.Errorf("attempts %d <= 0", attempts))
}