refactor: replace fmt.Errorf/errors.New with coreerr.E()
Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
parent
978e153615
commit
ab77e922bd
6 changed files with 81 additions and 62 deletions
16
actions.go
16
actions.go
|
|
@ -4,6 +4,8 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
coreerr "forge.lthn.ai/core/go-log"
|
||||
)
|
||||
|
||||
// Action represents a browser action that can be performed.
|
||||
|
|
@ -43,7 +45,7 @@ func (a NavigateAction) Execute(ctx context.Context, wv *Webview) error {
|
|||
"url": a.URL,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to navigate: %w", err)
|
||||
return coreerr.E("NavigateAction.Execute", "failed to navigate", err)
|
||||
}
|
||||
return wv.waitForLoad(ctx)
|
||||
}
|
||||
|
|
@ -191,7 +193,7 @@ func (a HoverAction) Execute(ctx context.Context, wv *Webview) error {
|
|||
}
|
||||
|
||||
if elem.BoundingBox == nil {
|
||||
return fmt.Errorf("element has no bounding box")
|
||||
return coreerr.E("HoverAction.Execute", "element has no bounding box", nil)
|
||||
}
|
||||
|
||||
x := elem.BoundingBox.X + elem.BoundingBox.Width/2
|
||||
|
|
@ -459,7 +461,7 @@ func (s *ActionSequence) WaitForSelector(selector string) *ActionSequence {
|
|||
func (s *ActionSequence) Execute(ctx context.Context, wv *Webview) error {
|
||||
for i, action := range s.actions {
|
||||
if err := action.Execute(ctx, wv); err != nil {
|
||||
return fmt.Errorf("action %d failed: %w", i, err)
|
||||
return coreerr.E("ActionSequence.Execute", fmt.Sprintf("action %d failed", i), err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
|
@ -492,18 +494,18 @@ func (wv *Webview) DragAndDrop(sourceSelector, targetSelector string) error {
|
|||
// Get source and target elements
|
||||
source, err := wv.querySelector(ctx, sourceSelector)
|
||||
if err != nil {
|
||||
return fmt.Errorf("source element not found: %w", err)
|
||||
return coreerr.E("Webview.DragAndDrop", "source element not found", err)
|
||||
}
|
||||
if source.BoundingBox == nil {
|
||||
return fmt.Errorf("source element has no bounding box")
|
||||
return coreerr.E("Webview.DragAndDrop", "source element has no bounding box", nil)
|
||||
}
|
||||
|
||||
target, err := wv.querySelector(ctx, targetSelector)
|
||||
if err != nil {
|
||||
return fmt.Errorf("target element not found: %w", err)
|
||||
return coreerr.E("Webview.DragAndDrop", "target element not found", err)
|
||||
}
|
||||
if target.BoundingBox == nil {
|
||||
return fmt.Errorf("target element has no bounding box")
|
||||
return coreerr.E("Webview.DragAndDrop", "target element has no bounding box", nil)
|
||||
}
|
||||
|
||||
// Calculate center points
|
||||
|
|
|
|||
10
angular.go
10
angular.go
|
|
@ -5,6 +5,8 @@ import (
|
|||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
coreerr "forge.lthn.ai/core/go-log"
|
||||
)
|
||||
|
||||
// AngularHelper provides Angular-specific testing utilities.
|
||||
|
|
@ -43,7 +45,7 @@ func (ah *AngularHelper) waitForAngular(ctx context.Context) error {
|
|||
return err
|
||||
}
|
||||
if !isAngular {
|
||||
return fmt.Errorf("not an Angular application")
|
||||
return coreerr.E("AngularHelper.waitForAngular", "not an Angular application", nil)
|
||||
}
|
||||
|
||||
// Wait for Zone.js stability
|
||||
|
|
@ -238,7 +240,7 @@ func (ah *AngularHelper) NavigateByRouter(path string) error {
|
|||
|
||||
_, err := ah.wv.evaluate(ctx, script)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to navigate: %w", err)
|
||||
return coreerr.E("AngularHelper.NavigateByRouter", "failed to navigate", err)
|
||||
}
|
||||
|
||||
// Wait for navigation to complete
|
||||
|
|
@ -279,13 +281,13 @@ func (ah *AngularHelper) GetRouterState() (*AngularRouterState, error) {
|
|||
}
|
||||
|
||||
if result == nil {
|
||||
return nil, fmt.Errorf("could not get router state")
|
||||
return nil, coreerr.E("AngularHelper.GetRouterState", "could not get router state", nil)
|
||||
}
|
||||
|
||||
// Parse result
|
||||
resultMap, ok := result.(map[string]any)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid router state format")
|
||||
return nil, coreerr.E("AngularHelper.GetRouterState", "invalid router state format", nil)
|
||||
}
|
||||
|
||||
state := &AngularRouterState{
|
||||
|
|
|
|||
45
cdp.go
45
cdp.go
|
|
@ -3,7 +3,6 @@ package webview
|
|||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"iter"
|
||||
"net/http"
|
||||
|
|
@ -12,6 +11,8 @@ import (
|
|||
"sync/atomic"
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
|
||||
coreerr "forge.lthn.ai/core/go-log"
|
||||
)
|
||||
|
||||
// CDPClient handles communication with Chrome DevTools Protocol via WebSocket.
|
||||
|
|
@ -78,18 +79,18 @@ func NewCDPClient(debugURL string) (*CDPClient, error) {
|
|||
// Get available targets
|
||||
resp, err := http.Get(debugURL + "/json")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get targets: %w", err)
|
||||
return nil, coreerr.E("CDPClient.New", "failed to get targets", err)
|
||||
}
|
||||
defer func() { _ = resp.Body.Close() }()
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read targets: %w", err)
|
||||
return nil, coreerr.E("CDPClient.New", "failed to read targets", err)
|
||||
}
|
||||
|
||||
var targets []TargetInfo
|
||||
if err := json.Unmarshal(body, &targets); err != nil {
|
||||
return nil, fmt.Errorf("failed to parse targets: %w", err)
|
||||
return nil, coreerr.E("CDPClient.New", "failed to parse targets", err)
|
||||
}
|
||||
|
||||
// Find a page target
|
||||
|
|
@ -105,31 +106,31 @@ func NewCDPClient(debugURL string) (*CDPClient, error) {
|
|||
// Try to create a new target
|
||||
resp, err := http.Get(debugURL + "/json/new")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("no page targets found and failed to create new: %w", err)
|
||||
return nil, coreerr.E("CDPClient.New", "no page targets found and failed to create new", err)
|
||||
}
|
||||
defer func() { _ = resp.Body.Close() }()
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read new target: %w", err)
|
||||
return nil, coreerr.E("CDPClient.New", "failed to read new target", err)
|
||||
}
|
||||
|
||||
var newTarget TargetInfo
|
||||
if err := json.Unmarshal(body, &newTarget); err != nil {
|
||||
return nil, fmt.Errorf("failed to parse new target: %w", err)
|
||||
return nil, coreerr.E("CDPClient.New", "failed to parse new target", err)
|
||||
}
|
||||
|
||||
wsURL = newTarget.WebSocketDebuggerURL
|
||||
}
|
||||
|
||||
if wsURL == "" {
|
||||
return nil, fmt.Errorf("no WebSocket URL available")
|
||||
return nil, coreerr.E("CDPClient.New", "no WebSocket URL available", nil)
|
||||
}
|
||||
|
||||
// Connect to WebSocket
|
||||
conn, _, err := websocket.DefaultDialer.Dial(wsURL, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to connect to WebSocket: %w", err)
|
||||
return nil, coreerr.E("CDPClient.New", "failed to connect to WebSocket", err)
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
|
|
@ -185,7 +186,7 @@ func (c *CDPClient) Call(ctx context.Context, method string, params map[string]a
|
|||
err := c.conn.WriteJSON(msg)
|
||||
c.mu.Unlock()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to send message: %w", err)
|
||||
return nil, coreerr.E("CDPClient.Call", "failed to send message", err)
|
||||
}
|
||||
|
||||
// Wait for response
|
||||
|
|
@ -194,7 +195,7 @@ func (c *CDPClient) Call(ctx context.Context, method string, params map[string]a
|
|||
return nil, ctx.Err()
|
||||
case resp := <-respCh:
|
||||
if resp.Error != nil {
|
||||
return nil, fmt.Errorf("CDP error %d: %s", resp.Error.Code, resp.Error.Message)
|
||||
return nil, coreerr.E("CDPClient.Call", resp.Error.Message, nil)
|
||||
}
|
||||
return resp.Result, nil
|
||||
}
|
||||
|
|
@ -293,28 +294,28 @@ func (c *CDPClient) NewTab(url string) (*CDPClient, error) {
|
|||
|
||||
resp, err := http.Get(endpoint)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create new tab: %w", err)
|
||||
return nil, coreerr.E("CDPClient.NewTab", "failed to create new tab", err)
|
||||
}
|
||||
defer func() { _ = resp.Body.Close() }()
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read response: %w", err)
|
||||
return nil, coreerr.E("CDPClient.NewTab", "failed to read response", err)
|
||||
}
|
||||
|
||||
var target TargetInfo
|
||||
if err := json.Unmarshal(body, &target); err != nil {
|
||||
return nil, fmt.Errorf("failed to parse target: %w", err)
|
||||
return nil, coreerr.E("CDPClient.NewTab", "failed to parse target", err)
|
||||
}
|
||||
|
||||
if target.WebSocketDebuggerURL == "" {
|
||||
return nil, fmt.Errorf("no WebSocket URL for new tab")
|
||||
return nil, coreerr.E("CDPClient.NewTab", "no WebSocket URL for new tab", nil)
|
||||
}
|
||||
|
||||
// Connect to new tab
|
||||
conn, _, err := websocket.DefaultDialer.Dial(target.WebSocketDebuggerURL, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to connect to new tab: %w", err)
|
||||
return nil, coreerr.E("CDPClient.NewTab", "failed to connect to new tab", err)
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
|
|
@ -350,18 +351,18 @@ func (c *CDPClient) CloseTab() error {
|
|||
func ListTargets(debugURL string) ([]TargetInfo, error) {
|
||||
resp, err := http.Get(debugURL + "/json")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get targets: %w", err)
|
||||
return nil, coreerr.E("ListTargets", "failed to get targets", err)
|
||||
}
|
||||
defer func() { _ = resp.Body.Close() }()
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read targets: %w", err)
|
||||
return nil, coreerr.E("ListTargets", "failed to read targets", err)
|
||||
}
|
||||
|
||||
var targets []TargetInfo
|
||||
if err := json.Unmarshal(body, &targets); err != nil {
|
||||
return nil, fmt.Errorf("failed to parse targets: %w", err)
|
||||
return nil, coreerr.E("ListTargets", "failed to parse targets", err)
|
||||
}
|
||||
|
||||
return targets, nil
|
||||
|
|
@ -386,18 +387,18 @@ func ListTargetsAll(debugURL string) iter.Seq[TargetInfo] {
|
|||
func GetVersion(debugURL string) (map[string]string, error) {
|
||||
resp, err := http.Get(debugURL + "/json/version")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get version: %w", err)
|
||||
return nil, coreerr.E("GetVersion", "failed to get version", err)
|
||||
}
|
||||
defer func() { _ = resp.Body.Close() }()
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read version: %w", err)
|
||||
return nil, coreerr.E("GetVersion", "failed to read version", err)
|
||||
}
|
||||
|
||||
var version map[string]string
|
||||
if err := json.Unmarshal(body, &version); err != nil {
|
||||
return nil, fmt.Errorf("failed to parse version: %w", err)
|
||||
return nil, coreerr.E("GetVersion", "failed to parse version", err)
|
||||
}
|
||||
|
||||
return version, nil
|
||||
|
|
|
|||
2
go.mod
2
go.mod
|
|
@ -3,3 +3,5 @@ module forge.lthn.ai/core/go-webview
|
|||
go 1.26.0
|
||||
|
||||
require github.com/gorilla/websocket v1.5.3
|
||||
|
||||
require forge.lthn.ai/core/go-log v0.0.4
|
||||
|
|
|
|||
10
go.sum
10
go.sum
|
|
@ -1,2 +1,12 @@
|
|||
forge.lthn.ai/core/go-log v0.0.4 h1:KTuCEPgFmuM8KJfnyQ8vPOU1Jg654W74h8IJvfQMfv0=
|
||||
forge.lthn.ai/core/go-log v0.0.4/go.mod h1:r14MXKOD3LF/sI8XUJQhRk/SZHBE7jAFVuCfgkXoZPw=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
|
||||
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
|
|
|||
60
webview.go
60
webview.go
|
|
@ -30,6 +30,8 @@ import (
|
|||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
coreerr "forge.lthn.ai/core/go-log"
|
||||
)
|
||||
|
||||
// Webview represents a connection to a Chrome DevTools Protocol endpoint.
|
||||
|
|
@ -80,7 +82,7 @@ func WithDebugURL(url string) Option {
|
|||
return func(wv *Webview) error {
|
||||
client, err := NewCDPClient(url)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to connect to Chrome DevTools: %w", err)
|
||||
return coreerr.E("Webview.WithDebugURL", "failed to connect to Chrome DevTools", err)
|
||||
}
|
||||
wv.client = client
|
||||
return nil
|
||||
|
|
@ -125,13 +127,13 @@ func New(opts ...Option) (*Webview, error) {
|
|||
|
||||
if wv.client == nil {
|
||||
cancel()
|
||||
return nil, fmt.Errorf("no debug URL provided; use WithDebugURL option")
|
||||
return nil, coreerr.E("Webview.New", "no debug URL provided; use WithDebugURL option", nil)
|
||||
}
|
||||
|
||||
// Enable console capture
|
||||
if err := wv.enableConsole(); err != nil {
|
||||
cancel()
|
||||
return nil, fmt.Errorf("failed to enable console capture: %w", err)
|
||||
return nil, coreerr.E("Webview.New", "failed to enable console capture", err)
|
||||
}
|
||||
|
||||
return wv, nil
|
||||
|
|
@ -155,7 +157,7 @@ func (wv *Webview) Navigate(url string) error {
|
|||
"url": url,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to navigate: %w", err)
|
||||
return coreerr.E("Webview.Navigate", "failed to navigate", err)
|
||||
}
|
||||
|
||||
// Wait for page load
|
||||
|
|
@ -248,17 +250,17 @@ func (wv *Webview) Screenshot() ([]byte, error) {
|
|||
"format": "png",
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to capture screenshot: %w", err)
|
||||
return nil, coreerr.E("Webview.Screenshot", "failed to capture screenshot", err)
|
||||
}
|
||||
|
||||
dataStr, ok := result["data"].(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid screenshot data")
|
||||
return nil, coreerr.E("Webview.Screenshot", "invalid screenshot data", nil)
|
||||
}
|
||||
|
||||
data, err := base64.StdEncoding.DecodeString(dataStr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to decode screenshot: %w", err)
|
||||
return nil, coreerr.E("Webview.Screenshot", "failed to decode screenshot", err)
|
||||
}
|
||||
|
||||
return data, nil
|
||||
|
|
@ -294,7 +296,7 @@ func (wv *Webview) GetURL() (string, error) {
|
|||
|
||||
url, ok := result.(string)
|
||||
if !ok {
|
||||
return "", fmt.Errorf("invalid URL result")
|
||||
return "", coreerr.E("Webview.GetURL", "invalid URL result", nil)
|
||||
}
|
||||
|
||||
return url, nil
|
||||
|
|
@ -312,7 +314,7 @@ func (wv *Webview) GetTitle() (string, error) {
|
|||
|
||||
title, ok := result.(string)
|
||||
if !ok {
|
||||
return "", fmt.Errorf("invalid title result")
|
||||
return "", coreerr.E("Webview.GetTitle", "invalid title result", nil)
|
||||
}
|
||||
|
||||
return title, nil
|
||||
|
|
@ -337,7 +339,7 @@ func (wv *Webview) GetHTML(selector string) (string, error) {
|
|||
|
||||
html, ok := result.(string)
|
||||
if !ok {
|
||||
return "", fmt.Errorf("invalid HTML result")
|
||||
return "", coreerr.E("Webview.GetHTML", "invalid HTML result", nil)
|
||||
}
|
||||
|
||||
return html, nil
|
||||
|
|
@ -375,7 +377,7 @@ func (wv *Webview) Reload() error {
|
|||
|
||||
_, err := wv.client.Call(ctx, "Page.reload", nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to reload: %w", err)
|
||||
return coreerr.E("Webview.Reload", "failed to reload", err)
|
||||
}
|
||||
|
||||
return wv.waitForLoad(ctx)
|
||||
|
|
@ -541,17 +543,17 @@ func (wv *Webview) evaluate(ctx context.Context, script string) (any, error) {
|
|||
"returnByValue": true,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to evaluate script: %w", err)
|
||||
return nil, coreerr.E("Webview.evaluate", "failed to evaluate script", err)
|
||||
}
|
||||
|
||||
// Check for exception
|
||||
if exceptionDetails, ok := result["exceptionDetails"].(map[string]any); ok {
|
||||
if exception, ok := exceptionDetails["exception"].(map[string]any); ok {
|
||||
if description, ok := exception["description"].(string); ok {
|
||||
return nil, fmt.Errorf("JavaScript error: %s", description)
|
||||
return nil, coreerr.E("Webview.evaluate", description, nil)
|
||||
}
|
||||
}
|
||||
return nil, fmt.Errorf("JavaScript error")
|
||||
return nil, coreerr.E("Webview.evaluate", "JavaScript error", nil)
|
||||
}
|
||||
|
||||
// Extract result value
|
||||
|
|
@ -567,17 +569,17 @@ func (wv *Webview) querySelector(ctx context.Context, selector string) (*Element
|
|||
// Get document root
|
||||
docResult, err := wv.client.Call(ctx, "DOM.getDocument", nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get document: %w", err)
|
||||
return nil, coreerr.E("Webview.querySelector", "failed to get document", err)
|
||||
}
|
||||
|
||||
root, ok := docResult["root"].(map[string]any)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid document root")
|
||||
return nil, coreerr.E("Webview.querySelector", "invalid document root", nil)
|
||||
}
|
||||
|
||||
rootID, ok := root["nodeId"].(float64)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid root node ID")
|
||||
return nil, coreerr.E("Webview.querySelector", "invalid root node ID", nil)
|
||||
}
|
||||
|
||||
// Query selector
|
||||
|
|
@ -586,12 +588,12 @@ func (wv *Webview) querySelector(ctx context.Context, selector string) (*Element
|
|||
"selector": selector,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to query selector: %w", err)
|
||||
return nil, coreerr.E("Webview.querySelector", "failed to query selector", err)
|
||||
}
|
||||
|
||||
nodeID, ok := queryResult["nodeId"].(float64)
|
||||
if !ok || nodeID == 0 {
|
||||
return nil, fmt.Errorf("element not found: %s", selector)
|
||||
return nil, coreerr.E("Webview.querySelector", "element not found: "+selector, nil)
|
||||
}
|
||||
|
||||
return wv.getElementInfo(ctx, int(nodeID))
|
||||
|
|
@ -602,17 +604,17 @@ func (wv *Webview) querySelectorAll(ctx context.Context, selector string) ([]*El
|
|||
// Get document root
|
||||
docResult, err := wv.client.Call(ctx, "DOM.getDocument", nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get document: %w", err)
|
||||
return nil, coreerr.E("Webview.querySelectorAll", "failed to get document", err)
|
||||
}
|
||||
|
||||
root, ok := docResult["root"].(map[string]any)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid document root")
|
||||
return nil, coreerr.E("Webview.querySelectorAll", "invalid document root", nil)
|
||||
}
|
||||
|
||||
rootID, ok := root["nodeId"].(float64)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid root node ID")
|
||||
return nil, coreerr.E("Webview.querySelectorAll", "invalid root node ID", nil)
|
||||
}
|
||||
|
||||
// Query selector all
|
||||
|
|
@ -621,12 +623,12 @@ func (wv *Webview) querySelectorAll(ctx context.Context, selector string) ([]*El
|
|||
"selector": selector,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to query selector all: %w", err)
|
||||
return nil, coreerr.E("Webview.querySelectorAll", "failed to query selector all", err)
|
||||
}
|
||||
|
||||
nodeIDs, ok := queryResult["nodeIds"].([]any)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid node IDs")
|
||||
return nil, coreerr.E("Webview.querySelectorAll", "invalid node IDs", nil)
|
||||
}
|
||||
|
||||
elements := make([]*ElementInfo, 0, len(nodeIDs))
|
||||
|
|
@ -653,7 +655,7 @@ func (wv *Webview) getElementInfo(ctx context.Context, nodeID int) (*ElementInfo
|
|||
|
||||
node, ok := descResult["node"].(map[string]any)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid node description")
|
||||
return nil, coreerr.E("Webview.getElementInfo", "invalid node description", nil)
|
||||
}
|
||||
|
||||
tagName, _ := node["nodeName"].(string)
|
||||
|
|
@ -726,7 +728,7 @@ func (wv *Webview) click(ctx context.Context, selector string) error {
|
|||
"clickCount": 1,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to dispatch %s: %w", eventType, err)
|
||||
return coreerr.E("Webview.click", "failed to dispatch "+eventType, err)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -739,7 +741,7 @@ func (wv *Webview) typeText(ctx context.Context, selector, text string) error {
|
|||
script := fmt.Sprintf("document.querySelector(%q)?.focus()", selector)
|
||||
_, err := wv.evaluate(ctx, script)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to focus element: %w", err)
|
||||
return coreerr.E("Webview.typeText", "failed to focus element", err)
|
||||
}
|
||||
|
||||
// Type each character
|
||||
|
|
@ -749,14 +751,14 @@ func (wv *Webview) typeText(ctx context.Context, selector, text string) error {
|
|||
"text": string(char),
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to dispatch keyDown: %w", err)
|
||||
return coreerr.E("Webview.typeText", "failed to dispatch keyDown", err)
|
||||
}
|
||||
|
||||
_, err = wv.client.Call(ctx, "Input.dispatchKeyEvent", map[string]any{
|
||||
"type": "keyUp",
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to dispatch keyUp: %w", err)
|
||||
return coreerr.E("Webview.typeText", "failed to dispatch keyUp", err)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue