htmldriver

package module
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 2, 2025 License: MIT Imports: 5 Imported by: 1

README

htmldriver

Test Lint Go Report Card codecov GoDoc

A lightweight Go library for automated testing of pure HTML with human-like interactions.

  • Load existing HTML strings (SSR output, templates, files, snapshots)
  • Emulate form input/submission, link/button clicks
  • Verify headings, lists, tables, and arbitrary text
  • No JavaScript execution (limited to pure HTML + Web standards)

日本語ドキュメント (Japanese)


Table of Contents


Why htmldriver?

When testing SSR applications or HTML templates in Go, existing tools have limitations:

  • goquery: Specialized for DOM parsing, lacks form submission and HTTP request capabilities
  • net/http/httptest: Can build mock servers, but form operation APIs aren't intuitive
  • playwright-go / chromedp: Headless browsers are heavy, slow to start, and overkill when JavaScript execution is unnecessary

htmldriver is optimized for SSR/template testing with these characteristics:

  • Lightweight: Only HTML parsing and HTTP requests (no browser required)
  • Intuitive API: Human-like expressions such as Fill(), Submit(), Click()
  • Transport abstraction: Integrates with any HTTP client/framework
  • Test framework agnostic: No dependency on the testing package

Features

  • Simple API: Intuitive operations for form input and link clicks
  • Transport abstraction: Works with any HTTP client/server
  • Automatic cookie management: Supports session maintenance and authentication scenarios
  • Lightweight: Few dependencies, easy setup

Limitations

  • No JavaScript support: Limited to pure HTML + Web standard behavior
  • No CSS/layout evaluation: Cannot detect visual breakage (text/DOM structure only)
  • No browser-specific behavior: Does not reproduce browser implementation differences

If you need JavaScript execution, consider headless browser libraries like playwright-go or chromedp.

Installation

go get github.com/ppdx999/htmldriver

Quick Start

package login_test

import (
    "net/http"
    "testing"

    h "github.com/ppdx999/htmldriver"
)

type MockTransport struct{}

func (m MockTransport) Do(req h.Request) (h.Response, error) {
    // Return arbitrary response based on submitted form/URL
    if req.Method == http.MethodPost && req.URL.Path == "/login" {
        user := req.Form.Get("username")
        return h.Response{Status: 200, Body: "<p>Welcome, " + user + "</p>"}, nil
    }
    return h.Response{Status: 404, Body: "not found"}, nil
}

func Test_LoginFlow(t *testing.T) {
    html := `
    <form id="login-form" action="/login" method="post">
      <label>User</label><input type="text" name="username">
      <label>Pass</label><input type="password" name="password">
      <button type="submit">Login</button>
    </form>`

    dom := h.New(MockTransport{}).Parse(html)

    form, err := dom.Form("#login-form")
    if err != nil {
        t.Fatal(err)
    }

    form.MustFill("username", "alice").MustFill("password", "secret")

    res, err := form.Submit()
    if err != nil {
        t.Fatal(err)
    }

    if res.Status != 200 {
        t.Fatalf("expected status 200, got %d", res.Status)
    }
}

Form Operations

Error Handling Version
form, err := dom.Form("@login")
if err != nil {
    return err
}

form, err = form.Fill("username", "tester")
if err != nil {
    return err
}

form, err = form.Fill("password", "mypassword")
if err != nil {
    return err
}

form, err = form.CheckCheckbox("remember_me")
if err != nil {
    return err
}

res, err := form.Submit()
if err != nil {
    return err
}

if res.Status != 200 {
    return fmt.Errorf("expected status 200, got %d", res.Status)
}
Method Chaining Version (Must*)

For tests where you want to fail immediately on error, use Must prefixed methods. These panic on error.

form, err := dom.Form("@login")
if err != nil {
    return err
}

form.MustFill("username", "tester").
    MustFill("password", "mypassword").
    MustCheckCheckbox("remember_me")

res, err := form.Submit()
if err != nil {
    return err
}

if res.Status != 200 {
    return fmt.Errorf("expected status 200, got %d", res.Status)
}
link, err := dom.Link("@profile")
if err != nil {
    return err
}

text, err := link.GetText()
if err != nil {
    return err
}
if text != "View Profile" {
    return fmt.Errorf("expected link text 'View Profile', got '%s'", text)
}

url, err := link.GetURL()
if err != nil {
    return err
}
if url.Path != "/users/123" {
    return fmt.Errorf("expected link URL '/users/123', got '%s'", url.Path)
}

res, err := link.Click()
if err != nil {
    return err
}

if res.Status != 200 {
    return fmt.Errorf("expected status 200, got %d", res.Status)
}

Finding Arbitrary Elements

You can find any HTML element using standard CSS selectors with Find():

// Find element by class
errorAlert, err := dom.Find(".alert-danger")
if err != nil {
    return err
}

// Get element text
errorText := errorAlert.Text()

// Get element attributes
className := errorAlert.Attr("class")
dataValue := errorAlert.Attr("data-value")

// Check if attribute exists
if errorAlert.HasAttr("data-error") {
    // Handle error attribute
}

// Get HTML content
html, err := errorAlert.HTML()

// Check element type
if errorAlert.Is(".alert") {
    // It's an alert
}

You can also find elements within forms:

form, _ := dom.Form("#login-form")

// Find input field within form
emailField, err := form.Find("#email")
if err != nil {
    return err
}

// Get field value from attribute
emailValue := emailField.Attr("value")

Making GET Requests

You can make GET requests directly and get a new DOM:

// Create initial DOM
dom := h.New(transport).Parse(html)

// Make GET request and get new DOM
homePage, err := dom.Get("/home")
if err != nil {
    return err
}

// Or use MustGet (panics on error)
homePage := dom.MustGet("/home")

// Cookies are automatically carried forward
profilePage := homePage.MustGet("/profile")

Table / List Verification

Table
table, err := dom.Table("@user-list")
if err != nil {
    return err
}

rows, err := table.GetRows()
if err != nil {
    return err
}

// Verify row count
if table.GetRowCount() != 3 {
    return fmt.Errorf("expected 3 rows, got %d", table.GetRowCount())
}

// Verify cell content
if rows[0][0] != "Alice" {
    return fmt.Errorf("expected 'Alice', got '%s'", rows[0][0])
}

// Check for empty table
if table.GetRowCount() == 0 {
    return fmt.Errorf("expected data, but table is empty")
}
List
list, err := dom.List("@todo-items")
if err != nil {
    return err
}

items, err := list.GetItems()
if err != nil {
    return err
}

// Verify item count
if list.GetItemCount() != 5 {
    return fmt.Errorf("expected 5 items, got %d", list.GetItemCount())
}

// Verify content
if items[0] != "Buy groceries" {
    return fmt.Errorf("expected 'Buy groceries', got '%s'", items[0])
}

Note: Advanced comparison and diff display are planned in the roadmap.

Continuous Operations

Submit() and Click() return a Response containing HTML body, which can be parsed again for the next operation.

To share cookies across multiple page operations, explicitly create and share a CookieJar.

// Create transport
transport := NewMockTransport()

// Create CookieJar for sharing cookies
jar := h.NewCookieJar()

// Login page
dom := h.NewWithCookieJar(transport, jar).Parse(loginPageHTML)

form, err := dom.Form("#login-form")
if err != nil {
    return err
}

form.MustFill("username", "alice").MustFill("password", "secret")

res, err := form.Submit()
if err != nil {
    return err
}

// Parse dashboard (use same jar)
dashboardDOM := h.NewWithCookieJar(transport, jar).Parse(res.Body)

// Click edit profile link
link, err := dashboardDOM.Link("@edit-profile")
if err != nil {
    return err
}

res, err = link.Click()
if err != nil {
    return err
}

// Parse edit page (use same jar)
editDOM := h.NewWithCookieJar(transport, jar).Parse(res.Body)

form, err = editDOM.Form("#profile-form")
if err != nil {
    return err
}

form.MustFill("bio", "Updated bio text")

res, err = form.Submit()
if err != nil {
    return err
}

if res.Status != 200 {
    return fmt.Errorf("expected status 200, got %d", res.Status)
}
Method 2: Reuse the Same DOM Instance

To automatically carry cookies forward, you can also repeatedly call Parse() on the same DOM instance.

transport := NewMockTransport()

// First page
dom := h.New(transport).Parse(loginPageHTML)

// Login
form, _ := dom.Form("#login-form")
form.MustFill("username", "alice").MustFill("password", "secret")
res, _ := form.Submit()

// Parse next page with same DOM (cookies are automatically carried)
dom = dom.Parse(res.Body)

// Continue using dom...

Important: Creating a new DOM with New() does not carry cookies forward. Use NewWithCookieJar() to share a CookieJar, or keep using the same DOM instance.

htmldriver automatically saves cookies from responses and sends them with subsequent form submissions or link clicks. This makes it easy to test session management and user authentication scenarios.

To set cookies beforehand:

dom := h.New(transport).Parse(html)
dom.SetCookie("session_id", "abc123")

// Subsequent operations will send "session_id=abc123"
form, err := dom.Form("#protected-form")
if err != nil {
    return err
}

form.MustFill("data", "value")

res, err := form.Submit()
if err != nil {
    return err
}

if res.Status != 200 {
    return fmt.Errorf("expected status 200, got %d", res.Status)
}

Note: Detailed cookie attributes (expiration, path, domain, Secure, HttpOnly, etc.) are planned in the roadmap.

Selectors

The selector parameter accepts two types of locator strings:

Selector Description
@xxxxx Matches elements with test-id attribute equal to xxxxx
#xxxxx Matches elements with id attribute equal to xxxxx

Support for more advanced CSS selectors is being considered in the roadmap.

Transport

Transport is an interface that abstracts I/O operations.

Form.Submit() and Link.Click() internally call Transport.Do() to send HTTP requests and return the results to the caller.

This mechanism allows htmldriver to work with any HTTP client or server framework without being tied to a specific implementation.

type Request struct {
    Method string
    URL    *url.URL
    Header http.Header
    Form   url.Values    // for x-www-form-urlencoded
    Files  []FormFile    // for multipart
}

type Response struct {
    Header http.Header
    URL    *url.URL
    Body   string
    Status int
}

type Transport interface {
    Do(req Request) (Response, error)
}
Example: Using Standard http.Client
type HTTPClientTransport struct {
    client  *http.Client
    baseURL string
}

func NewHTTPClientTransport(baseURL string) *HTTPClientTransport {
    return &HTTPClientTransport{
        client:  &http.Client{},
        baseURL: baseURL,
    }
}

func (t *HTTPClientTransport) Do(req h.Request) (h.Response, error) {
    // Convert relative URL to absolute URL
    fullURL := t.baseURL + req.URL.String()

    var httpReq *http.Request
    var err error

    if req.Method == http.MethodPost {
        httpReq, err = http.NewRequest(req.Method, fullURL, strings.NewReader(req.Form.Encode()))
        if err != nil {
            return h.Response{}, err
        }
        httpReq.Header.Set("Content-Type", "application/x-www-form-urlencoded")
    } else {
        httpReq, err = http.NewRequest(req.Method, fullURL, nil)
        if err != nil {
            return h.Response{}, err
        }
    }

    // Copy headers
    for k, v := range req.Header {
        httpReq.Header[k] = v
    }

    resp, err := t.client.Do(httpReq)
    if err != nil {
        return h.Response{}, err
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        return h.Response{}, err
    }

    return h.Response{
        Header: resp.Header,
        URL:    resp.Request.URL,
        Body:   string(body),
        Status: resp.StatusCode,
    }, nil
}
Base URL Handling

When form action or <a> href are relative paths, the Transport manages the base URL.

  • Default: Uses http://localhost
  • Customization: Specify baseURL when implementing Transport

API Overview

// Root
func New(transport Transport) *DOM
func NewWithCookieJar(transport Transport, jar *CookieJar) *DOM
func NewCookieJar() *CookieJar
func (d *DOM) Parse(html string) *DOM
func (d *DOM) SetCookie(name, value string) *DOM
func (d *DOM) GetCookieJar() *CookieJar
func (d *DOM) Get(url string) (*DOM, error)                    // Make GET request
func (d *DOM) MustGet(url string) *DOM                         // Make GET request (panic on error)

// Element Retrieval
func (d *DOM) Form(selector string) (*Form, error)
func (d *DOM) Link(selector string) (*Link, error)
func (d *DOM) Button(selector string) (*Button, error)
func (d *DOM) Table(selector string) (*Table, error)
func (d *DOM) List(selector string) (*List, error)
func (d *DOM) Text(selector string) (string, error)
func (d *DOM) Title() (string, error)
func (d *DOM) Meta(name string) (string, error)
func (d *DOM) Img(selector string) (*Img, error)
func (d *DOM) Find(selector string) (*Element, error)         // Find arbitrary element

// Form Operations (Error-returning version)
func (f *Form) Fill(name, value string) (*Form, error)           // Text input
func (f *Form) CheckCheckbox(name string) (*Form, error)         // Check checkbox
func (f *Form) UncheckCheckbox(name string) (*Form, error)       // Uncheck checkbox
func (f *Form) Select(name, value string) (*Form, error)         // Select option
func (f *Form) CheckRadio(name, value string) (*Form, error)     // Select radio
func (f *Form) Submit() (Response, error)                        // Submit

// Form Operations (Method chaining version - panics on error)
func (f *Form) MustFill(name, value string) *Form                // Text input
func (f *Form) MustCheckCheckbox(name string) *Form              // Check checkbox
func (f *Form) MustUncheckCheckbox(name string) *Form            // Uncheck checkbox
func (f *Form) MustSelect(name, value string) *Form              // Select option
func (f *Form) MustCheckRadio(name, value string) *Form          // Select radio

// Form Information
func (f *Form) GetValue(name string) (string, error)             // Get value
func (f *Form) HasField(name string) bool                        // Check field exists
func (f *Form) Find(selector string) (*Element, error)           // Find element in form

// Element
func (e *Element) Text() string                                  // Get text content
func (e *Element) Attr(name string) string                       // Get attribute value
func (e *Element) HasAttr(name string) bool                      // Check if attribute exists
func (e *Element) HTML() (string, error)                         // Get inner HTML
func (e *Element) Is(selector string) bool                       // Check if matches selector

// Link
func (l *Link) Click() (Response, error)
func (l *Link) GetURL() (*url.URL, error)
func (l *Link) GetText() (string, error)

// Button
func (b *Button) GetText() (string, error)

// Table
func (tbl *Table) GetRows() ([][]string, error)
func (tbl *Table) GetRowCount() int
func (tbl *Table) GetColCount() int

// List
func (lst *List) GetItems() ([]string, error)
func (lst *List) GetItemCount() int

// Image
func (img *Img) GetSrc() (string, error)
func (img *Img) GetAlt() (string, error)

Framework Integrations

Transport implementations for major HTTP server frameworks are provided.

Chi Integration

When using the Chi framework, you can use ChiTransport to work with httptest.Server.

import (
    "github.com/go-chi/chi/v5"
    h "github.com/ppdx999/htmldriver"
    "github.com/ppdx999/htmldriver/integrations/chitransport"
)

func Test_LoginFlow(t *testing.T) {
    r := chi.NewRouter()

    transport := chitransport.NewChiTransport(r)

    dom := h.New(transport).Parse(renderLoginPage())

    form, err := dom.Form("#login-form")
    if err != nil {
        t.Fatal(err)
    }

    form.MustFill("username", "alice").
        MustFill("password", "secret")

    res, err := form.Submit()
    if err != nil {
        t.Fatal(err)
    }

    if res.Status != 200 {
        t.Fatalf("expected status 200, got %d", res.Status)
    }
}
Echo Integration

Coming soon...

Gin Integration

Coming soon...

Fiber Integration

Coming soon...

Roadmap

  • multipart/form-data and file upload support
  • <select multiple> / <input type=date|time|number> input helpers
  • Redirect following (3xx) support
  • Detailed cookie attribute support (expiration, path, domain, Secure, HttpOnly, etc.)
  • Enhanced Table/List diff reporting (detailed cell mismatch display)
  • Rich selector extensions (class, tag, attribute selectors, :has(), :nth-of-type(), etc.)
  • Improved error messages with color diff output

License

MIT License - see LICENSE file for details

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Button

type Button struct {
	// contains filtered or unexported fields
}

Button represents an HTML button element

func (*Button) GetText

func (b *Button) GetText() (string, error)

GetText returns the text content of the button

type CookieJar

type CookieJar struct {
	// contains filtered or unexported fields
}

CookieJar stores cookies across requests

func NewCookieJar

func NewCookieJar() *CookieJar

NewCookieJar creates a new cookie jar

type DOM

type DOM struct {
	// contains filtered or unexported fields
}

DOM represents a parsed HTML document

func New

func New(transport Transport) *DOM

New creates a new DOM instance with the given transport Cookies are NOT shared between DOM instances by default

func NewWithCookieJar

func NewWithCookieJar(transport Transport, jar *CookieJar) *DOM

NewWithCookieJar creates a new DOM instance with a shared cookie jar Use this to share cookies across multiple DOM instances

func (*DOM) Button

func (d *DOM) Button(selector string) (*Button, error)

Button finds and returns a button element matching the selector

func (*DOM) Find added in v0.2.0

func (d *DOM) Find(selector string) (*Element, error)

Find finds and returns a generic element matching the selector Supports standard CSS selectors

func (*DOM) Form

func (d *DOM) Form(selector string) (*Form, error)

Form finds and returns a form element matching the selector

Example

Example from README

html := `
	<form id="login-form" action="/login" method="post">
		<label>User</label><input type="text" name="username">
		<label>Pass</label><input type="password" name="password">
		<button type="submit">Login</button>
	</form>`

dom := New(SimpleMockTransport{}).Parse(html)

form, err := dom.Form("#login-form")
if err != nil {
	fmt.Println(err)
	return
}

form.MustFill("username", "alice").MustFill("password", "secret")

res, err := form.Submit()
if err != nil {
	fmt.Println(err)
	return
}

if res.Status != 200 {
	fmt.Printf("expected status 200, got %d\n", res.Status)
	return
}

fmt.Println("Login successful")
Output:
Login successful

func (*DOM) Get added in v0.2.0

func (d *DOM) Get(urlStr string) (*DOM, error)

Get makes a GET request to the specified URL and returns a new DOM with the response

Example
transport := NewMockTransport()
transport.AddResponse("GET", "/home", 200, "<h1>Home</h1>")

dom := New(transport).Parse("<html></html>")

// Make GET request and get new DOM
homeDom := dom.MustGet("/home")

h1, _ := homeDom.Find("h1")
_ = h1.Text() // "Home"

func (*DOM) GetCookieJar

func (d *DOM) GetCookieJar() *CookieJar

GetCookieJar returns the cookie jar for sharing across DOM instances

func (*DOM) Img

func (d *DOM) Img(selector string) (*Img, error)

Img finds and returns an img element matching the selector

func (d *DOM) Link(selector string) (*Link, error)

Link finds and returns a link element matching the selector

func (*DOM) List

func (d *DOM) List(selector string) (*List, error)

List finds and returns a list element matching the selector

func (*DOM) Meta

func (d *DOM) Meta(name string) (string, error)

Meta returns the content of a meta tag by name

func (*DOM) MustGet added in v0.2.0

func (d *DOM) MustGet(urlStr string) *DOM

MustGet is like Get but panics on error

func (*DOM) Parse

func (d *DOM) Parse(html string) *DOM

Parse parses the given HTML string and returns the DOM

func (*DOM) SetBaseURL

func (d *DOM) SetBaseURL(baseURL string) (*DOM, error)

SetBaseURL sets the base URL for resolving relative URLs

func (*DOM) SetCookie

func (d *DOM) SetCookie(name, value string) *DOM

SetCookie sets a cookie that will be sent with subsequent requests

func (*DOM) Table

func (d *DOM) Table(selector string) (*Table, error)

Table finds and returns a table element matching the selector

func (*DOM) Text

func (d *DOM) Text(selector string) (string, error)

Text returns the text content of an element matching the selector

func (*DOM) Title

func (d *DOM) Title() (string, error)

Title returns the page title

type Element added in v0.2.0

type Element struct {
	// contains filtered or unexported fields
}

Element represents a generic HTML element

Example

Example usage of new APIs

html := `
	<div class="alert alert-danger">
		<strong>Error:</strong> Invalid input
	</div>`

dom := New(NewMockTransport()).Parse(html)

// Find element by CSS selector
alert, _ := dom.Find(".alert-danger")

// Get text content
text := alert.Text()
_ = text // "Error: Invalid input"

// Get attribute
className := alert.Attr("class")
_ = className // "alert alert-danger"

func (*Element) Attr added in v0.2.0

func (e *Element) Attr(name string) string

Attr returns the value of the specified attribute Returns empty string if attribute doesn't exist

func (*Element) HTML added in v0.2.0

func (e *Element) HTML() (string, error)

HTML returns the HTML content of the element

func (*Element) HasAttr added in v0.2.0

func (e *Element) HasAttr(name string) bool

HasAttr returns true if the element has the specified attribute

func (*Element) Is added in v0.2.0

func (e *Element) Is(selector string) bool

Is checks if the element matches the given selector

func (*Element) Text added in v0.2.0

func (e *Element) Text() string

Text returns the text content of the element

type Form

type Form struct {
	// contains filtered or unexported fields
}

Form represents an HTML form element

func (*Form) CheckCheckbox

func (f *Form) CheckCheckbox(name string) (*Form, error)

CheckCheckbox checks a checkbox

func (*Form) CheckRadio

func (f *Form) CheckRadio(name, value string) (*Form, error)

CheckRadio selects a radio button with the given value

func (*Form) Fill

func (f *Form) Fill(name, value string) (*Form, error)

Fill sets the value of a form field

func (*Form) Find added in v0.2.0

func (f *Form) Find(selector string) (*Element, error)

Find finds and returns a generic element within the form matching the selector Supports standard CSS selectors

func (*Form) GetValue

func (f *Form) GetValue(name string) (string, error)

GetValue returns the current value of a form field

func (*Form) HasField

func (f *Form) HasField(name string) bool

HasField returns true if the form has a field with the given name

func (*Form) MustCheckCheckbox

func (f *Form) MustCheckCheckbox(name string) *Form

MustCheckCheckbox is like CheckCheckbox but panics on error

func (*Form) MustCheckRadio

func (f *Form) MustCheckRadio(name, value string) *Form

MustCheckRadio is like CheckRadio but panics on error

func (*Form) MustFill

func (f *Form) MustFill(name, value string) *Form

MustFill is like Fill but panics on error

func (*Form) MustSelect

func (f *Form) MustSelect(name, value string) *Form

MustSelect is like Select but panics on error

func (*Form) MustUncheckCheckbox

func (f *Form) MustUncheckCheckbox(name string) *Form

MustUncheckCheckbox is like UncheckCheckbox but panics on error

func (*Form) Select

func (f *Form) Select(name, value string) (*Form, error)

Select selects an option in a select element

func (*Form) Submit

func (f *Form) Submit() (Response, error)

Submit submits the form and returns the response

func (*Form) UncheckCheckbox

func (f *Form) UncheckCheckbox(name string) (*Form, error)

UncheckCheckbox unchecks a checkbox

type FormFile

type FormFile struct {
	FieldName string
	FileName  string
	Content   []byte
}

FormFile represents a file to be uploaded in a multipart form

type Img

type Img struct {
	// contains filtered or unexported fields
}

Img represents an HTML img element

func (*Img) GetAlt

func (i *Img) GetAlt() (string, error)

GetAlt returns the alt attribute of the image

func (*Img) GetSrc

func (i *Img) GetSrc() (string, error)

GetSrc returns the src attribute of the image

type Link struct {
	// contains filtered or unexported fields
}

Link represents an HTML anchor element

func (*Link) Click

func (l *Link) Click() (Response, error)

Click follows the link and returns the response

func (*Link) GetText

func (l *Link) GetText() (string, error)

GetText returns the text content of the link

func (*Link) GetURL

func (l *Link) GetURL() (*url.URL, error)

GetURL returns the URL of the link

type List

type List struct {
	// contains filtered or unexported fields
}

List represents an HTML list element (ul or ol)

func (*List) GetItemCount

func (l *List) GetItemCount() int

GetItemCount returns the number of items in the list

func (*List) GetItems

func (l *List) GetItems() ([]string, error)

GetItems returns all list items as a slice of strings

type Request

type Request struct {
	Method string
	URL    *url.URL
	Header http.Header
	Form   url.Values
	Files  []FormFile
}

Request represents an HTTP request to be sent via Transport

type Response

type Response struct {
	Header http.Header
	URL    *url.URL
	Body   string
	Status int
}

Response represents an HTTP response received from Transport

type Table

type Table struct {
	// contains filtered or unexported fields
}

Table represents an HTML table element

func (*Table) GetColCount

func (t *Table) GetColCount() int

GetColCount returns the number of columns in the first row

func (*Table) GetRowCount

func (t *Table) GetRowCount() int

GetRowCount returns the number of rows in the table

func (*Table) GetRows

func (t *Table) GetRows() ([][]string, error)

GetRows returns all rows in the table as a 2D string slice Each row is represented as a slice of cell contents

type Transport

type Transport interface {
	Do(req Request) (Response, error)
}

Transport is an interface that abstracts HTTP communication

Directories

Path Synopsis
integrations
chitransport module

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL