Skip to content

Latest commit

 

History

History
222 lines (148 loc) · 6.87 KB

File metadata and controls

222 lines (148 loc) · 6.87 KB
title description
Development Guide
How to build, test, and contribute to go-webview -- prerequisites, test patterns, coding standards, and extension guides.

Development Guide

Prerequisites

Go

Go 1.26 or later is required. The module path is dappco.re/go/core/webview.

Chrome or Chromium

A running Chrome or Chromium instance with the remote debugging port enabled is required for any tests or usage that exercises the CDP connection. The package does not launch Chrome itself.

Start Chrome with the remote debugging port:

# macOS
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome \
    --remote-debugging-port=9222

# Linux
google-chrome --remote-debugging-port=9222

# Headless (suitable for CI)
google-chrome \
    --headless=new \
    --remote-debugging-port=9222 \
    --no-sandbox \
    --disable-gpu

The default debug URL is http://localhost:9222. Verify it is reachable by visiting http://localhost:9222/json in a browser or with curl.

Dependencies

The only runtime dependency is github.com/gorilla/websocket v1.5.3, declared in go.mod. Fetch dependencies with:

go mod download

Build and Test

Running Tests

go test ./...

Tests must pass before committing. The integration tests in webview_test.go that reference a live browser (TestNew_Bad_InvalidDebugURL) are designed to fail gracefully -- they assert that the error is non-nil when connecting to an unavailable port.

# Run a specific test
go test -v -run TestActionSequence_Good ./...

# Run all tests with verbose output
go test -v ./...

Vetting and Formatting

gofmt -w .
go vet ./...

Test Naming Convention

Tests follow the _Good, _Bad, _Ugly suffix pattern, consistent with the broader Core Go ecosystem:

  • _Good -- happy path, verifies correct behaviour under valid input.
  • _Bad -- expected error conditions, verifies that errors are returned and have the correct shape.
  • _Ugly -- panic/edge cases, unexpected or degenerate inputs.

All test functions use the standard testing.T interface; the project does not use a test framework.

Headless CI Tests

To add tests that exercise the full CDP stack in CI:

  1. Start Chrome in headless mode in the CI job before running go test.
  2. Serve test fixtures using net/http/httptest so tests do not depend on external URLs.
  3. Use WithTimeout to set conservative deadlines appropriate for the CI environment.

Code Organisation

New source files belong in the root package (package webview). The package is intentionally a single flat package; do not create sub-packages.

Keep separation between layers:

Layer File Guidance
CDP transport cdp.go Do not put browser-level logic here.
High-level API webview.go Methods here should be safe to call from application code without CDP knowledge.
Action types actions.go Add new action types here; keep each action focused on a single interaction.
Diagnostics console.go Console and exception capture live here.
SPA helpers angular.go Framework-specific helpers belong here or in a new file named after the framework (e.g. react.go, vue.go).

Coding Standards

Language

UK English throughout all source comments, documentation, commit messages, and identifiers where natural language appears. Use "colour", "organisation", "behaviour", "initialise", not their American equivalents.

Formatting

Standard gofmt formatting is mandatory. Run before committing:

gofmt -w .

Types and Error Handling

  • All exported functions must have Go doc comments.
  • Use fmt.Errorf("context: %w", err) for error wrapping so callers can use errors.Is and errors.As.
  • Return errors; do not panic in library code.
  • Use context.Context for all operations that involve I/O or waiting so callers can impose deadlines.

Concurrency

  • Protect shared mutable state with sync.RWMutex (read lock for reads, write lock for writes).
  • Do not call handlers or callbacks while holding a lock. Copy the slice of handlers, release the lock, then call them.
  • CDP WebSocket writes are serialised with a dedicated mutex in CDPClient; do not write to conn directly from outside cdp.go.

Licence Header

Every Go source file must begin with:

// SPDX-License-Identifier: EUPL-1.2

The project is licenced under the European Union Public Licence 1.2 (EUPL-1.2).

Commit Guidelines

Use conventional commits:

type(scope): description

Common types: feat, fix, docs, test, refactor, chore.

Example scopes: cdp, angular, console, actions.

All commits must include the co-author trailer:

Co-Authored-By: Virgil <[email protected]>

Full example:

feat(console): add ExceptionWatcher with stack trace capture

Subscribes to Runtime.exceptionThrown events and exposes a reactive
WaitForException API consistent with ConsoleWatcher.

Co-Authored-By: Virgil <[email protected]>

Adding a New Action Type

  1. Define a struct in actions.go with exported fields for the action's parameters.
  2. Implement Execute(ctx context.Context, wv *Webview) error on the struct.
  3. Add a builder method on ActionSequence that appends the new action.
  4. Add a _Good test in webview_test.go that verifies the struct fields are set correctly.

Example:

// SubmitAction submits a form element.
type SubmitAction struct {
    Selector string
}

func (a SubmitAction) Execute(ctx context.Context, wv *Webview) error {
    script := fmt.Sprintf("document.querySelector(%q)?.submit()", a.Selector)
    _, err := wv.evaluate(ctx, script)
    return err
}

func (s *ActionSequence) Submit(selector string) *ActionSequence {
    return s.Add(SubmitAction{Selector: selector})
}

Adding a New Angular Helper

Add methods to AngularHelper in angular.go. Follow the established pattern:

  1. Obtain a context with the helper's timeout using context.WithTimeout.
  2. Build the JavaScript as a self-invoking function expression (function() { ... })().
  3. Call ah.wv.evaluate(ctx, script) to execute it.
  4. After state-modifying operations, call TriggerChangeDetection() or inline appRef.tick().
  5. For polling-based waits, use a time.NewTicker at 100 ms and select over ctx.Done().

Adding a New SPA Framework Helper

To add support for a different single-page application framework (e.g. React, Vue):

  1. Create a new file named after the framework (e.g. react.go).
  2. Define a helper struct that holds a *Webview reference and a configurable timeout.
  3. Use evaluate() to inject JavaScript that probes framework-specific globals and APIs.
  4. Follow the same context.WithTimeout + polling pattern established in angular.go.

Forge Push

Push to the canonical remote via SSH:

git push ssh://[email protected]:2223/core/go-webview.git HEAD:main

HTTPS authentication is not available on this remote.