A WebDriver client and acceptance testing library for Go

Agouti

Build Status GoDoc

#agouti IRC on Freenode

Agouti is a library for writing browser-based acceptance tests in Google Go. It provides Gomega matchers and plays nicely with Ginkgo or Spec. See agouti.org and the GoDoc for documentation. Have questions? Check out the Agouti mailing list or the #agouti IRC channel on Freenode.

The integration tests are a great place to see everything in action and get started quickly!

Owner
Stephen Levine
Tech Lead, App Ops @ VMware Tanzu | Core team maintainer of CNCF's Cloud Native Buildpacks (buildpacks.io)
Stephen Levine
Comments
  • More documentation on how to use RunScript properly

    More documentation on how to use RunScript properly

    Background: I'm trying to make sure a javascript-populated list on my page has the correct contents. I tried to check the HTML of the page by itself, but that doesn't update with the javascript changes...

    So instead, I'm trying to pull information out of the javascript-heavy page and ensure that it contains what I expect, so I wrote code like this (replace 100 with something like window.App.getCount() for example):

    var number int
    Expect(page.RunScript("return 100;", nil, &number)).To(Succeed())
    Expect(number).To(Equal(100))
    

    That didn't work however, and the RunScript fails with this error: "failed to run script: request unsuccessful: error unreadable"

    Am I using Agouti wrong (is it not meant to probe the running web driver instance)? I would have at least expecte dit to return the 100 as an integer.

  • Load and Close Chrome Silently and driver.Stop crashing

    Load and Close Chrome Silently and driver.Stop crashing

    Hi,

    I am using Agouti to Scrape a web page. Everything It is working ok except that the chrome window remains opened after the processing is finished.

    When I call driver.stop like this:

        if err := driver.Stop(); err != nil {
            log.Fatal("Failed to close pages and stop WebDriver:", err)
        }
    
    

    I receive the error message:

    Failed to close pages and stop WebDriver:failed to stop service: failed to stop command: TerminateProcess: Access is denied.

    Why is the stop crashing? Is this why the chrome window is not closed at the end ?

    By the way I am opening like this:

    func openSelenium(options ...agouti.Option) *agouti.WebDriver {
        command := []string{"java", "-jar", "<path>\\selenium-server-standalone-2.53.0.jar", "-port", "5555"}
        return agouti.NewWebDriver("http://127.0.0.1:5555/wd/hub", command, options...)
    }
    

    The Chromedriver is in the path.

    Thanks

  • Selenium Hub

    Selenium Hub

    I'm trying to run the generated suite_test but I'm using Selenium Hub in a Docker container. I think I need to use NewWebDriver but I can't figure out why I have to pass a command? I already have it running.

  • appium docs

    appium docs

    @abourget @sclevine I'm super excited about the Appium support but getting my test suite up and running is quite painful. So far I'm getting to the point where my webdriver isn't getting a session ID:

    failed to connect to WebDriver: failed to connect to WebDriver: failed to retrieve a session ID
    

    A quick example to get started would be super useful.

    Thanks

  • First draft of SwitchTo() and Windows handling.

    First draft of SwitchTo() and Windows handling.

    This PR is for discussions, is untested, just to clarify the API design.

    I need to list, close and switch windows. The WebDrivers specs talk about that (window_handle and window_handles and DELETE to close, etc..).. Capybara also has support for such things.

    What would be the best approach to do this ? Normally, the window related functions would be on the Session.. but here we have a Page object at hand most of the time. It might add a bit of confusion to talk about pages and windows as different things, so I'm unsure where we can steer this.

    I've gone through the CONTRIBUTIONS.md file.. anything specific you'd require to merge such a proposition ?

    thanks for the great lib btw :)

  • First(

    First("not_there").Visible() generates a bad protocol request

    This manifests as:

    failed to determine whether selection 'CSS: not_there [0]' is visible: request unsuccessful: error parsing response: invalid character 'u' looking for beginning of value

    The actual value it was trying to parse is:

    unknown command: session/[garble]/element/displayed

    Which appears to be caused by the use of path.Join() in api/element.go. Specifically, when an indexed selector matches nothing, you get an Element.ID == "". This generates a Selenium request of the form "[...]/element/displayed" rather than "[...]/element//displayed". The latter won't work either, but at least Selenium doesn't choke on it, generating a non-JSON response.


    The second part, of which I'm a bit less sure, is why it's possible to get an Element.ID == "" in the first place. This doesn't seem to happen with non-indexed selectors (e.g., All("not_there").Visible()) -- this generates the more sane response failed to select elements from selection 'CSS: not_there': no elements found. I'm still trying to make sense of precisely how this should work, but I suspect it shouldn't be generating element instances without their IDs set.

  • Mac OS-specific way to start Selenium server

    Mac OS-specific way to start Selenium server

    The "selenium-server" script that must be in the path seems to be installed by the brew recipe.. however I didn't find the equivalent on Linux. I was thinking of adding SeleniumJar() that would launch the .jar file through java -jar whatever.jar.is.in.the.current.directory.jar.

    What do you think ?

  • HaveCSS matcher should match reasonable CSS color equivalents, etc.

    HaveCSS matcher should match reasonable CSS color equivalents, etc.

    For instance, adding style="color: blue;" to an element does not match HaveCSS("color","blue"), because PhantomJS returns RGBA.

  • Implemented Windows() to retrieve the open windows.

    Implemented Windows() to retrieve the open windows.

    This is needed to close the windows, window.name is always empty and WebDriver doesn't read that I think.

    I know tests are missing.. haven't looked at the testing machinery in there.. It works in my app though.

    What do you think ? This way we keep types.Window behind the scene.

  • Any way to check for javascript errors?

    Any way to check for javascript errors?

    It would be nice if Agouti could report any javascript errors that occur on a page so that I could include a check for this in my application's acceptance tests. Is there any way to do this currently?

  • where is the page.Find tested? (or: examples needed)

    where is the page.Find tested? (or: examples needed)

    I only see a lot of tests that are written with the other 2 packages (ginkgo & gomega) but no separate agouti only tests. I was looking for a way to use find, and since the documentation is not that clear about the usage, I thought to look inside the tests, but I don't seem to find it.

    I was trying to see if there is a string inside a page:

    	someVar := page.Find("ERR_NAME_NOT_RESOLVED")
    	fmt.Println(someVar)
    

    but that didn't do the trick. Find only reacts on selectors.

    So basically to check if an URL is a good one, I use this:

    	someVar := page.Find(".error-code")
    	someCount, err := someVar.Count()
    	if err == nil {
    		if someCount > 0 {
    			text, err := someVar.Text()
    			if err == nil {
    				if strings.Contains(text, "ERR_NAME_NOT_RESOLVED") {
    					fmt.Println("URL cannot be found")
    				}
    			}
    		}
    	}
    

    Isn't there a better way to achieve this? I think a string compare to find out an url isn't a good one is a bit buggy, so I'm looking for advice here.

  • Failing webdriver session should be handled, not silently ignored.

    Failing webdriver session should be handled, not silently ignored.

    Hi,

    I was having issues when calling Page.Navigate() and got the error failed to navigate: failed request: invalid session id. After some digging in the code I got to the point where the session got initiated.

    Here the response from the chromedriver:

    HTTP/1.1 200 OK
    Content-Length:503
    Content-Type:application/json; charset=utf-8
    
    {"sessionId":"51576e1fde8127c51faf316a072d9123","status":13,"value":{"message":"unknown error: Chrome failed to start: exited abnormally.\n  (unknown error: DevToolsActivePort file doesn't exist)\n  (The process started from chrome location /usr/lib64/chromium/chromium is no longer running, so ChromeDriver is assuming that Chrome has crashed.)\n  (Driver info: chromedriver=84.0.4147.89 (19abfe7bcba9318a0b2a6bc6634a67fc834aa592-refs/branch-heads/4147@{#852}),platform=Linux 5.7.9-1-default x86_64)"}}
    

    As we can see, obviously the session is in some bad state and it would be nice to fail right here with the message from the chromedriver.

    Instead failing at Page.Navigate(), fail me at Driver.NewPage() and the received message. The status 13 must mean something in the protocol, i guess.

    Ciao Pierre

  • Feature Request: Documentation on picking a dropdown

    Feature Request: Documentation on picking a dropdown

    It would be helpful if some documentation or example could show how to select an option from a dropdown select. For example here: http://jsfiddle.net/t0xicCode/96ntuxnz/

    <select name="People" class="selectpicker" data-style="btn-default" data-width="100%" multiple>
        <option value="John">John</option>
        <option value="Paul">Paul</option>
        <option value="Mary">Mary</option>
        <option value="Jane">Jane</option>
        <option value="Elisa">Elisa</option>
    </select>
    
    $('.selectpicker').selectpicker();
    $('.selectpicker').selectpicker('val', ['John', 'Paul']);
    

    I guess you could add an ID to the select, but how would you walk the option value list and select it?

    Please and thank you,

  • Added NewWithArgs to allow starting of the appium service with arguments

    Added NewWithArgs to allow starting of the appium service with arguments

    My target use-case is starting the appium service with "--relaxed-security". The other approach I considered was to allow more directly creating the appium.WebDriver struct so clients could provide an existing agouti.WebDriver.

    Hopefully this PR is in an acceptable form - I've not done this often :)

A yaml data-driven testing format together with golang testing library

Specimen Yaml-based data-driven testing Specimen is a yaml data format for data-driven testing. This enforces separation between feature being tested

Nov 24, 2022
siusiu (suite-suite harmonics) a suite used to manage the suite, designed to free penetration testing engineers from learning and using various security tools, reducing the time and effort spent by penetration testing engineers on installing tools, remembering how to use tools.
siusiu (suite-suite harmonics) a suite used to manage the suite, designed to free penetration testing engineers from learning and using various security tools, reducing the time and effort spent by penetration testing engineers on installing tools, remembering how to use tools.

siusiu (suite-suite harmonics) a suite used to manage the suite, designed to free penetration testing engineers from learning and using various security tools, reducing the time and effort spent by penetration testing engineers on installing tools, remembering how to use tools.

Dec 12, 2022
Fortio load testing library, command line tool, advanced echo server and web UI in go (golang). Allows to specify a set query-per-second load and record latency histograms and other useful stats.
Fortio load testing library, command line tool, advanced echo server and web UI in go (golang). Allows to specify a set query-per-second load and record latency histograms and other useful stats.

Fortio Fortio (Φορτίο) started as, and is, Istio's load testing tool and now graduated to be its own project. Fortio is also used by, among others, Me

Jan 2, 2023
Golang HTTP client testing framework

flute Golang HTTP client testing framework Presentation https://speakerdeck.com/szksh/flute-golang-http-client-testing-framework Overview flute is the

Sep 27, 2022
go websocket client for unit testing of a websocket handler

wstest A websocket client for unit-testing a websocket server The gorilla organization provides full featured websocket implementation that the standa

Dec 21, 2022
mock server to aid testing the jaguar-java client API

stripe-mock stripe-mock is a mock HTTP server that responds like the real Stripe API. It can be used instead of Stripe's test mode to make test suites

Dec 24, 2021
Client tool for testing HTTP server timeouts

HTTP timeout test client While testing Go HTTP server timeouts I wrote this little tool to help me test. It allows for slowing down header write and b

Sep 21, 2022
HTTP load testing tool and library. It's over 9000!
HTTP load testing tool and library. It's over 9000!

Vegeta Vegeta is a versatile HTTP load testing tool built out of a need to drill HTTP services with a constant request rate. It can be used both as a

Jan 7, 2023
:exclamation:Basic Assertion Library used along side native go testing, with building blocks for custom assertions

Package assert Package assert is a Basic Assertion library used along side native go testing Installation Use go get. go get github.com/go-playground/

Jan 6, 2023
Library created for testing JSON against patterns.

Gomatch Library created for testing JSON against patterns. The goal was to be able to validate JSON focusing only on parts essential in given test cas

Oct 28, 2022
A Go library help testing your RESTful API application

RESTit A Go micro-framework to help writing RESTful API integration test Package RESTit provides helps to those who want to write an integration test

Oct 28, 2022
testcase is an opinionated behavior-driven-testing library

Table of Contents testcase Guide Official API Documentation Getting Started / Example Modules Summary DRY Modularization Stability Case Study About te

Nov 10, 2022
Go library for testing async behavior

Helpers for testing async behavior.

Jun 30, 2022
Gostresslib - A golang library for stress testing.

GoStressLib A golang library for stress testing. Install go get github.com/tenhan/gostresslib Usage package main import ( "github.com/tenhan/gostres

Nov 9, 2022
Tesuto - a little library for testing against HTTP services

tesuto import "github.com/guregu/tesuto" tesuto is a little library for testing

Jan 18, 2022
A modern generic testing assertions library for Go

test test is a generics based testing assertions library for Go. There are two packages, test and must. test - assertions that mark the test for failu

Dec 12, 2022
Testing framework for Go. Allows writing self-documenting tests/specifications, and executes them concurrently and safely isolated. [UNMAINTAINED]

GoSpec GoSpec is a BDD-style testing framework for the Go programming language. It allows writing self-documenting tests/specs, and executes them in p

Nov 28, 2022
Extremely flexible golang deep comparison, extends the go testing package and tests HTTP APIs
Extremely flexible golang deep comparison, extends the go testing package and tests HTTP APIs

go-testdeep Extremely flexible golang deep comparison, extends the go testing package. Latest news Synopsis Description Installation Functions Availab

Dec 22, 2022
Minimal and Beautiful Go testing framework
Minimal and Beautiful Go testing framework

Goblin A Mocha like BDD testing framework written in Go that requires no additional dependencies. Requires no extensive documentation nor complicated

Dec 25, 2022