134 lines
3.7 KiB
Go
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
|
|
}
|