func CreateSession()

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))
}