Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions internal/js/modules/k6/browser/browser/mapping_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,7 @@ type pageAPI interface { //nolint:interfacebloat
GetByLabel(label string, opts *common.GetByBaseOptions) *common.Locator
GetByPlaceholder(placeholder string, opts *common.GetByBaseOptions) *common.Locator
GetByTitle(title string, opts *common.GetByBaseOptions) *common.Locator
GetByTestId(testID string) *common.Locator
GetKeyboard() *common.Keyboard
GetMouse() *common.Mouse
GetTouchscreen() *common.Touchscreen
Expand Down
6 changes: 6 additions & 0 deletions internal/js/modules/k6/browser/browser/page_mapping.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,12 @@ func mapPage(vu moduleVU, p *common.Page) mapping { //nolint:gocognit,cyclop
ml := mapLocator(vu, p.GetByTitle(ptitle, popts))
return rt.ToValue(ml).ToObject(rt), nil
},
"getByTestId": func(testID sobek.Value) (*sobek.Object, error) {
ptestID := parseStringOrRegex(testID, false)

ml := mapLocator(vu, p.GetByTestID(ptestID))
return rt.ToValue(ml).ToObject(rt), nil
},
"goto": func(url string, opts sobek.Value) (*sobek.Promise, error) {
gopts := common.NewFrameGotoOptions(
p.Referrer(),
Expand Down
7 changes: 7 additions & 0 deletions internal/js/modules/k6/browser/common/frame.go
Original file line number Diff line number Diff line change
Expand Up @@ -1146,6 +1146,13 @@ func (f *Frame) GetByTitle(title string, opts *GetByBaseOptions) *Locator {
return f.Locator("internal:attr="+f.buildAttributeSelector("title", title, opts), nil)
}

// GetByTestID creates and returns a new locator for this frame based on the data-testid attribute.
func (f *Frame) GetByTestID(testID string) *Locator {
f.log.Debugf("Frame:GetByTestID", "fid:%s furl:%q testID:%q", f.ID(), f.URL(), testID)

return f.Locator("internal:attr=[data-testid="+testID+"]", nil)
}

// Referrer returns the referrer of the frame from the network manager
// of the frame's session.
// It's an internal method not to be exposed as a JS API.
Expand Down
7 changes: 7 additions & 0 deletions internal/js/modules/k6/browser/common/page.go
Original file line number Diff line number Diff line change
Expand Up @@ -1123,6 +1123,13 @@ func (p *Page) GetByTitle(title string, opts *GetByBaseOptions) *Locator {
return p.MainFrame().GetByTitle(title, opts)
}

// GetByTestID creates and returns a new locator for this page (main frame) based on the data-testid attribute.
func (p *Page) GetByTestID(testID string) *Locator {
p.logger.Debugf("Page:GetByTestID", "sid:%s testID: %q", p.sessionID(), testID)

return p.MainFrame().GetByTestID(testID)
}

// GetKeyboard returns the keyboard for the page.
func (p *Page) GetKeyboard() *Keyboard {
return p.Keyboard
Expand Down
87 changes: 87 additions & 0 deletions internal/js/modules/k6/browser/tests/get_by_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1099,3 +1099,90 @@ func TestGetByTitleSuccess(t *testing.T) {
})
}
}

func TestGetByTestIDSuccess(t *testing.T) {
t.Parallel()

tests := []struct {
name string
testID string
expected int
expectedText string
}{
{
"submit_button",
"'submit-button'",
1,
"Submit",
},
{
"username_input",
"'username-input'",
1,
"",
},
{
"info_box",
"'info-box'",
1,
"Information",
},
{
"regex_match",
`/^[a-z0-9]+$/`,
1,
"Test span",
},
{
"link_testid",
"'my-link'",
1,
"Link",
},
{
"non_existent_testid",
"'does-not-exist'",
0,
"",
},
{
"missing_testid",
"",
0,
"",
},
{
"empty_string",
"''",
0,
"",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()

tb := newTestBrowser(t, withFileServer())
p := tb.NewPage(nil)
opts := &common.FrameGotoOptions{
Timeout: common.DefaultTimeout,
}
_, err := p.Goto(
tb.staticURL("get_by_testid.html"),
opts,
)
require.NoError(t, err)

l := p.GetByTestID(tt.testID)
c, err := l.Count()
assert.NoError(t, err)
assert.Equal(t, tt.expected, c)

if tt.expected > 0 && tt.expectedText != "" {
text, err := l.InnerText(sobek.Undefined())
assert.NoError(t, err)
assert.Equal(t, tt.expectedText, text)
}
})
}
}
12 changes: 12 additions & 0 deletions internal/js/modules/k6/browser/tests/static/get_by_testid.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!DOCTYPE html>
<head>
<title>Test ID Selector Engine Test Suite</title>
</head>
<body>
<button data-testid="submit-button">Submit</button>
<input type="text" data-testid="username-input" placeholder="Username">
<div data-testid="info-box">Information</div>
<span data-testid="abc123">Test span</span>
<a href="#" data-testid="my-link">Link</a>
</body>
</html>
Loading