dt_automate/vendor/github.com/playwright-community/playwright-go/locator_helpers.go
2025-02-19 18:30:19 +08:00

134 lines
3.7 KiB
Go

package playwright
import (
"encoding/json"
"fmt"
"regexp"
"strings"
)
func convertRegexp(reg *regexp.Regexp) (pattern, flags string) {
matches := regexp.MustCompile(`\(\?([imsU]+)\)(.+)`).FindStringSubmatch(reg.String())
if len(matches) == 3 {
pattern = matches[2]
flags = matches[1]
} else {
pattern = reg.String()
}
return
}
func escapeForAttributeSelector(text interface{}, exact bool) string {
switch text := text.(type) {
case *regexp.Regexp:
return escapeRegexForSelector(text)
default:
suffix := "i"
if exact {
suffix = "s"
}
return fmt.Sprintf(`"%s"%s`, strings.Replace(strings.Replace(text.(string), `\`, `\\`, -1), `"`, `\"`, -1), suffix)
}
}
func escapeForTextSelector(text interface{}, exact bool) string {
switch text := text.(type) {
case *regexp.Regexp:
return escapeRegexForSelector(text)
default:
if exact {
return fmt.Sprintf(`%ss`, escapeText(text.(string)))
}
return fmt.Sprintf(`%si`, escapeText(text.(string)))
}
}
func escapeRegexForSelector(re *regexp.Regexp) string {
pattern, flag := convertRegexp(re)
return fmt.Sprintf(`/%s/%s`, strings.ReplaceAll(pattern, `>>`, `\>\>`), flag)
}
func escapeText(s string) string {
builder := &strings.Builder{}
encoder := json.NewEncoder(builder)
encoder.SetEscapeHTML(false)
_ = encoder.Encode(s)
return strings.TrimSpace(builder.String())
}
func getByAltTextSelector(text interface{}, exact bool) string {
return getByAttributeTextSelector("alt", text, exact)
}
func getByAttributeTextSelector(attrName string, text interface{}, exact bool) string {
return fmt.Sprintf(`internal:attr=[%s=%s]`, attrName, escapeForAttributeSelector(text, exact))
}
func getByLabelSelector(text interface{}, exact bool) string {
return fmt.Sprintf(`internal:label=%s`, escapeForTextSelector(text, exact))
}
func getByPlaceholderSelector(text interface{}, exact bool) string {
return getByAttributeTextSelector("placeholder", text, exact)
}
func getByRoleSelector(role AriaRole, options ...LocatorGetByRoleOptions) string {
props := make(map[string]string)
if len(options) == 1 {
if options[0].Checked != nil {
props["checked"] = fmt.Sprintf("%t", *options[0].Checked)
}
if options[0].Disabled != nil {
props["disabled"] = fmt.Sprintf("%t", *options[0].Disabled)
}
if options[0].Selected != nil {
props["selected"] = fmt.Sprintf("%t", *options[0].Selected)
}
if options[0].Expanded != nil {
props["expanded"] = fmt.Sprintf("%t", *options[0].Expanded)
}
if options[0].IncludeHidden != nil {
props["include-hidden"] = fmt.Sprintf("%t", *options[0].IncludeHidden)
}
if options[0].Level != nil {
props["level"] = fmt.Sprintf("%d", *options[0].Level)
}
if options[0].Name != nil {
exact := false
if options[0].Exact != nil {
exact = *options[0].Exact
}
props["name"] = escapeForAttributeSelector(options[0].Name, exact)
}
if options[0].Pressed != nil {
props["pressed"] = fmt.Sprintf("%t", *options[0].Pressed)
}
}
propsStr := ""
for k, v := range props {
propsStr += "[" + k + "=" + v + "]"
}
return fmt.Sprintf("internal:role=%s%s", role, propsStr)
}
func getByTextSelector(text interface{}, exact bool) string {
return fmt.Sprintf(`internal:text=%s`, escapeForTextSelector(text, exact))
}
func getByTestIdSelector(testIdAttributeName string, testId interface{}) string {
return fmt.Sprintf(`internal:testid=[%s=%s]`, testIdAttributeName, escapeForAttributeSelector(testId, true))
}
func getByTitleSelector(text interface{}, exact bool) string {
return getByAttributeTextSelector("title", text, exact)
}
func getTestIdAttributeName() string {
return testIdAttributeName
}
func setTestIdAttributeName(name string) {
testIdAttributeName = name
}