sclevine / agouti

A WebDriver client and acceptance testing library for Go
MIT License
821 stars 105 forks source link

How to use IEDriverServer.exe by agouti? #142

Open nickhell opened 6 years ago

nickhell commented 6 years ago

i tried this code for managing ie: command := []string{"IEDriverServer.exe", "/port={{.Port}}"} agoutiDriver := agouti.NewWebDriver("http://{{.Address}}", command) capabilities := agouti.NewCapabilities().Browser("internet explorer").Without("javascriptEnabled") page,_ := agoutiDriver.NewPage(agouti.Desired(capabilities)) agoutiDriver.Start() page.Navigate("https://www.google.com")

but got the error in the last operation "page.Navigate('https://www.google.com')": GOROOT=D:\Program\Go #gosetup GOPATH=D:\p_data\gopath #gosetup D:\Program\Go\bin\go.exe build -i -o C:\Users\nick\AppData\Local\Temp_agouti_main_go.exe D:/studio/go/ra/agoutimain.go #gosetup "D:\Program\JetBrains\GoLand 173.3727.24\bin\runnerw.exe" C:\Users\nick\AppData\Local\Temp\agouti_main_go.exe #gosetup panic: runtime error: invalid memory address or nil pointer dereference [signal 0xc0000005 code=0x0 addr=0x0 pc=0x6c73ad]

goroutine 1 [running]: github.com/sclevine/agouti.(*Page).Navigate(0x0, 0x78dbc7, 0x15, 0x1, 0x0) D:/p_data/gopath/src/github.com/sclevine/agouti/page.go:116 +0x2d main.main() D:/studio/go/ra/agouti_main.go:22 +0x201

Process finished with exit code 2

how to work it? thanks.

nickhell commented 6 years ago

Because it works well in java by similar code, so i make sure the configuration of IEDriver(like %PATH%) is correct.

sclevine commented 6 years ago

Hi @nickhell,

I see two issues:

  1. You need to call agoutiDriver.Start() before you request a new page from the WebDriver with agoutiDriver.NewPage().
  2. You should check your error values. The nil pointer deref you're receiving is likely due to NewPage returning a nil page and non-nil error. If you checked that error, you would likely find a message letting you know that you need to start the WebDriver first.
nickhell commented 6 years ago

@sclevine thanks a lot of your suggestions. I follow your advice, and opened ie browser agent server, but also didn't work well. So I printed the error, found the error was "failed to connect to WebDriver: failed to retrieve a session ID" when called agoutiDriver.NewPage(agouti.Desired(capabilities)). I really don't know how to fix it. The screenshot like this: 20171126220038

nickhell commented 6 years ago

I got responseBody of func openSession(url string, body io.Reader, httpClient *http.Client) (sessionID string, err error) in agouti/api/internal/bus/connect.go like this:

{"value":{"capabilities":{"acceptInsecureCerts":false,"browserName":"internet explorer","browserVersion":"-1","pageLoadStrategy":"normal","platformName":"windows","proxy":{},"se:ieOptions":{"browserAttachTimeout":0,"elementScrollBehavior":0,"enablePersistentHover":true,"ie.browserCommandLineSwitches":"","ie.ensureCleanSession":false,"ie.fileUploadDialogTimeout":3000,"ie.forceCreateProcessApi":false,"ignoreProtectedModeSettings":false,"ignoreZoomSetting":false,"initialBrowserUrl":"http://localhost:65279/" ,"nativeEvents":true,"requireWindowFocus":false},"setWindowRect":true,"timeouts":{"implicit":0,"pageLoad":300000,"script":30000},"unhandledPromptBehavior":"dismiss"},"sessionId":"48653f69-cdaf-48f4-82a0-5983ed70c17f"}}

But err := json.Unmarshal(responseBody, &sessionResponse) in connect.go can't retrieve sessionResponse.SessionId.

nickhell commented 6 years ago

Hi @sclevine. I think the issue is a bug in file connect.go. I modify the file like this in line 72:

if sessionResponse.SessionID == "" {
        unmarshalForLoop(responseBody, &sessionResponse)
        if sessionResponse.SessionID == "" {
            return "", errors.New("failed to retrieve a session ID")
        }
    }

And the function unmarshalForLoop is:

func unmarshalForLoop(responseBody []byte, sessionResponse *struct{ SessionID string })(err error){
    var object map[string]interface{}
    json.Unmarshal(responseBody, &object)
    for _, value := range object{
        if err := json.Unmarshal(responseBody, &sessionResponse); err != nil {
            return err
        }
        if sessionResponse.SessionID == ""{
            data,_ := json.Marshal(value)
            return unmarshalForLoop(data, sessionResponse)
        }else{
            break
        }
    }
    return nil
}

I think my code is not elegant, could you optimize the project?