Skip to content
This repository has been archived by the owner on Dec 17, 2024. It is now read-only.

Commit

Permalink
Merge pull request #857 from vania-pooh/master
Browse files Browse the repository at this point in the history
Supporting firstMatch in capabilities (fixes #450)
  • Loading branch information
aandryashin authored Jan 13, 2020
2 parents 3642e6e + 3c23b2c commit 744a56e
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 40 deletions.
97 changes: 58 additions & 39 deletions selenoid.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import (
"encoding/json"
"fmt"
"github.com/aerokube/selenoid/event"
"github.com/aerokube/selenoid/service"
"github.com/imdario/mergo"
"io"
"io/ioutil"
"log"
Expand Down Expand Up @@ -119,7 +121,8 @@ func create(w http.ResponseWriter, r *http.Request) {
var browser struct {
Caps session.Caps `json:"desiredCapabilities"`
W3CCaps struct {
Caps session.Caps `json:"alwaysMatch"`
Caps session.Caps `json:"alwaysMatch"`
FirstMatch []*session.Caps `json:"firstMatch"`
} `json:"capabilities"`
}
err = json.Unmarshal(body, &browser)
Expand All @@ -132,41 +135,57 @@ func create(w http.ResponseWriter, r *http.Request) {
if browser.W3CCaps.Caps.BrowserName() != "" && browser.Caps.BrowserName() == "" {
browser.Caps = browser.W3CCaps.Caps
}
browser.Caps.ProcessExtensionCapabilities()
sessionTimeout, err := getSessionTimeout(browser.Caps.SessionTimeout, maxTimeout, timeout)
if err != nil {
log.Printf("[%d] [BAD_SESSION_TIMEOUT] [%s]", requestId, browser.Caps.SessionTimeout)
util.JsonError(w, err.Error(), http.StatusBadRequest)
queue.Drop()
return
}
resolution, err := getScreenResolution(browser.Caps.ScreenResolution)
if err != nil {
log.Printf("[%d] [BAD_SCREEN_RESOLUTION] [%s]", requestId, browser.Caps.ScreenResolution)
util.JsonError(w, err.Error(), http.StatusBadRequest)
queue.Drop()
return
}
browser.Caps.ScreenResolution = resolution
videoScreenSize, err := getVideoScreenSize(browser.Caps.VideoScreenSize, resolution)
if err != nil {
log.Printf("[%d] [BAD_VIDEO_SCREEN_SIZE] [%s]", requestId, browser.Caps.VideoScreenSize)
util.JsonError(w, err.Error(), http.StatusBadRequest)
queue.Drop()
return
}
browser.Caps.VideoScreenSize = videoScreenSize
finalVideoName := browser.Caps.VideoName
if browser.Caps.Video && !disableDocker {
browser.Caps.VideoName = getTemporaryFileName(videoOutputDir, videoFileExtension)
}
finalLogName := browser.Caps.LogName
if logOutputDir != "" && (saveAllLogs || browser.Caps.Log) {
browser.Caps.LogName = getTemporaryFileName(logOutputDir, logFileExtension)
firstMatchCaps := browser.W3CCaps.FirstMatch
if len(firstMatchCaps) == 0 {
firstMatchCaps = append(firstMatchCaps, &session.Caps{})
}
var caps session.Caps
var starter service.Starter
var ok bool
var sessionTimeout time.Duration
var finalVideoName, finalLogName string
for _, fmc := range firstMatchCaps {
caps = browser.Caps
mergo.Merge(&caps, *fmc)
caps.ProcessExtensionCapabilities()
sessionTimeout, err = getSessionTimeout(caps.SessionTimeout, maxTimeout, timeout)
if err != nil {
log.Printf("[%d] [BAD_SESSION_TIMEOUT] [%s]", requestId, caps.SessionTimeout)
util.JsonError(w, err.Error(), http.StatusBadRequest)
queue.Drop()
return
}
resolution, err := getScreenResolution(caps.ScreenResolution)
if err != nil {
log.Printf("[%d] [BAD_SCREEN_RESOLUTION] [%s]", requestId, caps.ScreenResolution)
util.JsonError(w, err.Error(), http.StatusBadRequest)
queue.Drop()
return
}
caps.ScreenResolution = resolution
videoScreenSize, err := getVideoScreenSize(caps.VideoScreenSize, resolution)
if err != nil {
log.Printf("[%d] [BAD_VIDEO_SCREEN_SIZE] [%s]", requestId, caps.VideoScreenSize)
util.JsonError(w, err.Error(), http.StatusBadRequest)
queue.Drop()
return
}
caps.VideoScreenSize = videoScreenSize
finalVideoName = caps.VideoName
if caps.Video && !disableDocker {
caps.VideoName = getTemporaryFileName(videoOutputDir, videoFileExtension)
}
finalLogName = caps.LogName
if logOutputDir != "" && (saveAllLogs || caps.Log) {
caps.LogName = getTemporaryFileName(logOutputDir, logFileExtension)
}
starter, ok = manager.Find(caps, requestId)
if ok {
break
}
}
starter, ok := manager.Find(browser.Caps, requestId)
if !ok {
log.Printf("[%d] [ENVIRONMENT_NOT_AVAILABLE] [%s] [%s]", requestId, browser.Caps.BrowserName(), browser.Caps.Version)
log.Printf("[%d] [ENVIRONMENT_NOT_AVAILABLE] [%s] [%s]", requestId, caps.BrowserName(), caps.Version)
util.JsonError(w, "Requested environment is not available", http.StatusBadRequest)
queue.Drop()
return
Expand Down Expand Up @@ -265,7 +284,7 @@ func create(w http.ResponseWriter, r *http.Request) {
}
sess := &session.Session{
Quota: user,
Caps: browser.Caps,
Caps: caps,
URL: u,
Container: startedService.Container,
HostPort: startedService.HostPort,
Expand All @@ -282,8 +301,8 @@ func create(w http.ResponseWriter, r *http.Request) {
SessionId: sessionId,
Session: sess,
}
if browser.Caps.Video && !disableDocker {
oldVideoName := filepath.Join(videoOutputDir, browser.Caps.VideoName)
if caps.Video && !disableDocker {
oldVideoName := filepath.Join(videoOutputDir, caps.VideoName)
if finalVideoName == "" {
finalVideoName = sessionId + videoFileExtension
e.Session.Caps.VideoName = finalVideoName
Expand All @@ -301,10 +320,10 @@ func create(w http.ResponseWriter, r *http.Request) {
event.FileCreated(createdFile)
}
}
if logOutputDir != "" && (saveAllLogs || browser.Caps.Log) {
if logOutputDir != "" && (saveAllLogs || caps.Log) {
//The following logic will fail if -capture-driver-logs is enabled and a session is requested in driver mode.
//Specifying both -log-output-dir and -capture-driver-logs in that case is considered a misconfiguration.
oldLogName := filepath.Join(logOutputDir, browser.Caps.LogName)
oldLogName := filepath.Join(logOutputDir, caps.LogName)
if finalLogName == "" {
finalLogName = sessionId + logFileExtension
e.Session.Caps.LogName = finalLogName
Expand Down
31 changes: 30 additions & 1 deletion selenoid_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,36 @@ func TestSessionCreated(t *testing.T) {
func TestSessionCreatedW3C(t *testing.T) {
manager = &HTTPTest{Handler: Selenium()}

resp, err := http.Post(With(srv.URL).Path("/wd/hub/session"), "", bytes.NewReader([]byte(`{"capabilities":{"alwaysMatch":{"acceptInsecureCerts":true,"browserName":"firefox", "browserVersion":"latest", "selenoid:options":{"enableVNC": true}}}}`)))
resp, err := http.Post(With(srv.URL).Path("/wd/hub/session"), "", bytes.NewReader([]byte(`{"capabilities":{"alwaysMatch":{"acceptInsecureCerts":true, "browserName":"firefox", "browserVersion":"latest", "selenoid:options":{"enableVNC": true}}}}`)))
AssertThat(t, err, Is{nil})
var sess map[string]string
AssertThat(t, resp, AllOf{Code{http.StatusOK}, IsJson{&sess}})

resp, err = http.Get(With(srv.URL).Path("/status"))
AssertThat(t, err, Is{nil})
var state config.State
AssertThat(t, resp, AllOf{Code{http.StatusOK}, IsJson{&state}})
AssertThat(t, state.Used, EqualTo{1})
AssertThat(t, queue.Used(), EqualTo{1})

versions, firefoxPresent := state.Browsers["firefox"]
AssertThat(t, firefoxPresent, Is{true})
users, versionPresent := versions["latest"]
AssertThat(t, versionPresent, Is{true})
userInfo, userPresent := users["unknown"]
AssertThat(t, userPresent, Is{true})
AssertThat(t, userInfo, Not{nil})
AssertThat(t, len(userInfo.Sessions), EqualTo{1})
AssertThat(t, userInfo.Sessions[0].VNC, EqualTo{true})

sessions.Remove(sess["sessionId"])
queue.Release()
}

func TestSessionCreatedFirstMatchOnly(t *testing.T) {
manager = &HTTPTest{Handler: Selenium()}

resp, err := http.Post(With(srv.URL).Path("/wd/hub/session"), "", bytes.NewReader([]byte(`{"capabilities":{"firstMatch":[{"browserName":"firefox", "browserVersion":"latest", "selenoid:options":{"enableVNC": true}}]}}`)))
AssertThat(t, err, Is{nil})
var sess map[string]string
AssertThat(t, resp, AllOf{Code{http.StatusOK}, IsJson{&sess}})
Expand Down

0 comments on commit 744a56e

Please sign in to comment.