Documentation
¶
Overview ¶
Package capybara is a pure-Go (CGO-free) reimplementation of the deterministic core of Ruby's `capybara` gem together with its default, browser-free `:rack_test` driver.
Capybara is an acceptance-test DSL: you drive a web application the way a user would — visit a path, click a link, fill in a form, assert that the resulting page contains some text — without ever touching a real browser. The default rack_test driver does this entirely in-process: it speaks to a Rack application directly (no sockets, no JavaScript), parses each HTML response, and mutates an in-memory DOM as the "user" interacts with it. Every follow-up request (a link's href, a form's action) is reconstructed from that DOM and handed back to the app.
This package reproduces that model in Go. The application under test is an injectable seam — an App func that maps a Request to a Response — so tests drive a plain Go function and never reach a network. In the go-embedded-ruby binding the seam wraps a real Ruby Rack app: the Request is converted to a Rack `env` hash, `app.call(env)` is invoked, and the `[status, headers, body]` triple is converted back into a Response.
Ruby surface it mirrors ¶
- Capybara::Session#visit / #current_path / #current_url
- #click_link / #click_button / #click_on
- #fill_in / #choose / #check / #uncheck / #select / #attach_file / #find_field
- #find / #all / #first
- #has_selector? / #has_content? / #has_text? / #has_link? / #has_button? / #has_field? / #has_css? / #has_xpath? and their negations
- #assert_selector / #assert_text and friends
- #within(scope) { ... }
- Node#text / #[] / #value / #click / #set / #tag_name / #checked? / #selected? / #visible?
Selectors ¶
The heart of the driver is an HTML parser (golang.org/x/net/html, pure Go) plus a query engine. Two low-level selector kinds are supported directly:
- CSS: type, universal (*), #id, .class, [attr], [attr=v], [attr~=v], [attr^=v], [attr$=v], [attr*=v], [attr|=v], the descendant ( ) and child (>) combinators, and comma-separated selector lists.
- XPath: a practical subset — // and / and .// steps, element or * node tests, and predicates over @attr, text(), contains(), position, and and/or.
On top of those, the semantic Capybara selectors (:link, :button, :field, :fillable_field, :checkbox, :radio_button, :select, :option, :link_or_button, :id, :css, :xpath) are implemented so that a plain string locator matches by id, name, label text, placeholder or visible text the way the gem does.
Index ¶
- type Ambiguous
- type App
- type ElementNotFound
- type ExpectationNotMet
- type InfiniteRedirect
- type Node
- func (n *Node) Attr(name string) (string, bool)
- func (n *Node) AttrOr(name, fallback string) string
- func (n *Node) Checked() bool
- func (n *Node) Click() error
- func (n *Node) Selected() bool
- func (n *Node) Set(value string) error
- func (n *Node) TagName() string
- func (n *Node) Text() string
- func (n *Node) Value() string
- func (n *Node) Visible() bool
- type ParseError
- type Request
- type Response
- type Session
- func (s *Session) All(sel string) ([]*Node, error)
- func (s *Session) AllXPath(sel string) ([]*Node, error)
- func (s *Session) AssertNoSelector(sel string) error
- func (s *Session) AssertNoText(text string) error
- func (s *Session) AssertSelector(sel string) error
- func (s *Session) AssertText(text string) error
- func (s *Session) AttachFile(locator, path string) error
- func (s *Session) Body() string
- func (s *Session) Check(locator string) error
- func (s *Session) Choose(locator string) error
- func (s *Session) ClickButton(locator string) error
- func (s *Session) ClickLink(locator string) error
- func (s *Session) ClickOn(locator string) error
- func (s *Session) CurrentPath() string
- func (s *Session) CurrentURL() string
- func (s *Session) FillIn(locator, with string) error
- func (s *Session) Find(sel string) (*Node, error)
- func (s *Session) FindButton(locator string) (*Node, error)
- func (s *Session) FindField(locator string) (*Node, error)
- func (s *Session) FindLink(locator string) (*Node, error)
- func (s *Session) FindXPath(sel string) (*Node, error)
- func (s *Session) First(sel string) (*Node, error)
- func (s *Session) HasButton(locator string) bool
- func (s *Session) HasContent(text string) bool
- func (s *Session) HasField(locator string) bool
- func (s *Session) HasLink(locator string) bool
- func (s *Session) HasNoButton(locator string) bool
- func (s *Session) HasNoContent(text string) bool
- func (s *Session) HasNoField(locator string) bool
- func (s *Session) HasNoLink(locator string) bool
- func (s *Session) HasNoSelector(sel string) bool
- func (s *Session) HasNoXPath(sel string) bool
- func (s *Session) HasSelector(sel string) bool
- func (s *Session) HasText(text string) bool
- func (s *Session) HasXPath(sel string) bool
- func (s *Session) Response() *Response
- func (s *Session) Select(value, from string) error
- func (s *Session) StatusCode() int
- func (s *Session) Uncheck(locator string) error
- func (s *Session) Visit(path string) error
- func (s *Session) Within(sel string, fn func() error) error
- type UnselectableError
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Ambiguous ¶
Ambiguous is returned when a singular finder matches more than one element. It mirrors Capybara::Ambiguous.
type App ¶
App is the seam between Capybara and the application under test. It is the Go analogue of a Rack app: it maps a Request to a Response. In tests it is a plain in-memory func; in the go-embedded-ruby binding it wraps a real Ruby Rack app (converting to/from the Rack `env` hash).
type ElementNotFound ¶
type ElementNotFound struct {
// Query is a human description of what was searched for, e.g.
// `link "Sign in"` or `css ".btn"`.
Query string
}
ElementNotFound is returned when a finder that expects exactly one match finds none. It mirrors Capybara::ElementNotFound.
func (*ElementNotFound) Error ¶
func (e *ElementNotFound) Error() string
type ExpectationNotMet ¶
type ExpectationNotMet struct {
Message string
}
ExpectationNotMet is returned by the assert_* helpers when a positive or negative expectation fails. It mirrors Capybara::ExpectationNotMet.
func (*ExpectationNotMet) Error ¶
func (e *ExpectationNotMet) Error() string
type InfiniteRedirect ¶
type InfiniteRedirect struct {
Limit int
}
InfiniteRedirect is returned when following redirects exceeds the driver's redirect limit. It mirrors Capybara::InfiniteRedirectError.
func (*InfiniteRedirect) Error ¶
func (e *InfiniteRedirect) Error() string
type Node ¶
type Node struct {
// contains filtered or unexported fields
}
Node is a single element found in the current document. It mirrors Capybara::Node::Element: it wraps a DOM node and a back-reference to the Session so that interactions (click/set/...) can issue new requests.
func (*Node) Attr ¶
Attr returns the value of the named attribute and whether it was present. It backs the Ruby Node#[] accessor.
func (*Node) Click ¶
Click performs the element's default action, mirroring Node#click: following a link's href, or submitting the form a button belongs to. Checkboxes and radios toggle. It returns an error if the element is not clickable.
func (*Node) Set ¶
Set assigns a value, mirroring Node#set. For text inputs and textareas it updates the value; for checkboxes/radios a bool-ish value toggles checked.
func (*Node) TagName ¶
TagName returns the lower-case tag name, e.g. "a", "input". It mirrors Node#tag_name.
func (*Node) Text ¶
Text returns the normalized visible text of the node, mirroring Node#text: descendant text nodes concatenated, runs of whitespace collapsed, trimmed. Text inside <script>/<style> and non-visible elements is excluded.
type ParseError ¶
type ParseError struct {
Err error
}
ParseError wraps a failure to parse an HTML response body.
func (*ParseError) Error ¶
func (e *ParseError) Error() string
func (*ParseError) Unwrap ¶
func (e *ParseError) Unwrap() error
type Request ¶
type Request struct {
// Method is the upper-case HTTP verb ("GET", "POST", ...).
Method string
// Path is the request path (PATH_INFO), always starting with "/".
Path string
// Query is the raw query string, without a leading "?".
Query string
// Body is the raw request body (rack.input).
Body string
// Header holds request headers such as Content-Type.
Header http.Header
// Scheme is "http" or "https" (rack.url_scheme).
Scheme string
// Host is the server name (SERVER_NAME).
Host string
}
Request is the driver's representation of a single HTTP request to the app. It carries enough to build the equivalent Rack `env` hash in the binding.
type Response ¶
Response is the app's reply: an HTTP status, headers, and a body. It is the Go analogue of a Rack response triple `[status, headers, body]`.
func NewResponse ¶
NewResponse is a convenience constructor for app authors and tests. The Content-Type defaults to text/html when contentType is empty.
type Session ¶
type Session struct {
// RedirectLimit bounds automatic redirect following (Capybara default 5).
RedirectLimit int
// Host is the SERVER_NAME used for requests (Capybara default
// "www.example.com"; here trimmed to "www.example.com").
Host string
// Scheme is the URL scheme for requests.
Scheme string
// contains filtered or unexported fields
}
Session drives an application under test, mirroring Capybara::Session with the default rack_test driver. Construct one with New.
func (*Session) AssertNoSelector ¶
AssertNoSelector returns an error if any visible element matches (Session#assert_no_selector).
func (*Session) AssertNoText ¶
AssertNoText returns an error if the scope contains text (Session#assert_no_text).
func (*Session) AssertSelector ¶
AssertSelector returns an ExpectationNotMet error unless a visible element matches the CSS selector (Session#assert_selector).
func (*Session) AssertText ¶
AssertText returns an ExpectationNotMet error unless the scope contains text (Session#assert_text).
func (*Session) AttachFile ¶
AttachFile finds a file input by locator and sets its value to path, mirroring Session#attach_file. Multipart encoding of the upload is out of scope for this subset; the path is submitted as the field value.
func (*Session) ClickButton ¶
ClickButton finds a button by locator and submits its form (Session#click_button).
func (*Session) ClickLink ¶
ClickLink finds a link by locator and follows its href (Session#click_link).
func (*Session) ClickOn ¶
ClickOn clicks a link or a button matching locator, whichever exists, mirroring Session#click_on / #click_link_or_button.
func (*Session) CurrentPath ¶
CurrentPath returns the path of the current page (Session#current_path).
func (*Session) CurrentURL ¶
CurrentURL returns the full URL of the current page (Session#current_url).
func (*Session) FillIn ¶
FillIn finds a fillable field by locator and sets its value to with, mirroring Session#fill_in(locator, with: value).
func (*Session) Find ¶
Find returns the single visible element matching the CSS selector, or an error if none (ElementNotFound) or several (Ambiguous) match. It mirrors Session#find with the default :css selector.
func (*Session) FindButton ¶
FindButton returns the single button matching locator, mirroring find(:button, locator).
func (*Session) FindField ¶
FindField returns the single field matching locator (id, name, placeholder or label), mirroring find(:field, locator).
func (*Session) FindLink ¶
FindLink returns the single link matching locator (id, title, text or image alt), mirroring find(:link, locator).
func (*Session) First ¶
First returns the first visible element matching the CSS selector, or an error if none match (Session#first).
func (*Session) HasButton ¶
HasButton reports whether a matching button is present (Session#has_button?).
func (*Session) HasContent ¶
HasContent reports whether the current scope's visible text contains text, after whitespace normalization (Session#has_content? / #has_text?).
func (*Session) HasField ¶
HasField reports whether a matching field is present (Session#has_field?).
func (*Session) HasNoButton ¶
HasNoButton is the negation of HasButton.
func (*Session) HasNoContent ¶
HasNoContent is the negation of HasContent (Session#has_no_content?).
func (*Session) HasNoField ¶
HasNoField is the negation of HasField.
func (*Session) HasNoSelector ¶
HasNoSelector is the negation of HasSelector (Session#has_no_selector?).
func (*Session) HasNoXPath ¶
HasNoXPath is the negation of HasXPath.
func (*Session) HasSelector ¶
HasSelector reports whether at least one visible element matches the CSS selector (Session#has_selector? / #has_css?).
func (*Session) Response ¶
Response returns the most recent raw Response, or nil before the first request. It backs Capybara's page.status_code / page.response_headers / page.body helpers.
func (*Session) Select ¶
Select chooses the option labelled value within the select identified by from, mirroring Session#select(value, from: locator). When the select is single-valued, previously selected options are cleared.
func (*Session) StatusCode ¶
StatusCode returns the last response's HTTP status.
func (*Session) Visit ¶
Visit issues a GET request for path (which may include a query string) and makes the response the current page, mirroring Session#visit.
type UnselectableError ¶
type UnselectableError struct {
Message string
}
UnselectableError is returned when set/choose/check is called on a node whose tag cannot receive that interaction (e.g. filling in a <div>).
func (*UnselectableError) Error ¶
func (e *UnselectableError) Error() string
