package extractor import ( "fmt" "strings" "github.com/playwright-community/playwright-go" ) type Node interface { Content() (string, error) Text() (string, error) Attr(name string) (string, error) Screenshot() ([]byte, error) Type(input string) error Click() error Select(selector string) Nodes SelectFirst(selector string) Node ForEach(selector string, fn func(Node) error) error SetHidden(val bool) error SetAttribute(name, value string) error } type node struct { locator playwright.Locator } func (n node) Type(input string) error { return n.locator.Type(input) } func (n node) Click() error { return n.locator.Click() } func (n node) Content() (string, error) { return n.locator.TextContent() } func (n node) Text() (string, error) { return n.locator.InnerText() } func (n node) Attr(name string) (string, error) { return n.locator.GetAttribute(name) } func (n node) Screenshot() ([]byte, error) { return n.locator.Screenshot() } func (n node) Select(selector string) Nodes { elements, err := n.locator.Locator(selector).All() if err != nil { return nil } var nodes Nodes for _, element := range elements { nodes = append(nodes, node{locator: element}) } return nodes } func (n node) SelectFirst(selector string) Node { return n.Select(selector).First() } func (n node) ForEach(selector string, fn func(Node) error) error { elements, err := n.locator.Locator(selector).All() if err != nil { return err } for _, element := range elements { if err := fn(node{locator: element}); err != nil { return err } } return nil } func (n node) SetHidden(val bool) error { _, err := n.locator.Evaluate(fmt.Sprintf(`(element) => element.hidden = %t;`, val), nil) return err } func escapeJavaScript(s string) string { return strings.Replace(strings.Replace(s, "\\", "\\\\", -1), "'", "\\'", -1) } func (n node) SetAttribute(name, value string) error { _, err := n.locator.Evaluate(fmt.Sprintf(`(element) => element.setAttribute('%s', '%s');`, escapeJavaScript(name), escapeJavaScript(value)), nil) return err }