Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Async Locator #1332

Merged
merged 29 commits into from
May 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
7bef3b5
Async Locator.Clear
inancgumus May 14, 2024
7fa8f3e
Async Locator.Dblclick
inancgumus May 14, 2024
2d4de1d
Async Locator.Check
inancgumus May 14, 2024
745d929
Async Locator.Uncheck
inancgumus May 14, 2024
6691250
Async Locator.IsChecked
inancgumus May 14, 2024
af7caee
Async Locator.IsEditable
inancgumus May 14, 2024
ea57b7f
Async Locator.IsEnabled
inancgumus May 14, 2024
59978e4
Async Locator.IsDisabled
inancgumus May 14, 2024
e5a8a74
Async Locator.IsVisible
inancgumus May 14, 2024
824389f
Async Locator.IsHidden
inancgumus May 14, 2024
2cd9e69
Async Locator.Fill
inancgumus May 14, 2024
a4e0cf7
Async Locator.Focus
inancgumus May 14, 2024
6167142
Async Locator.GetAttribute
inancgumus May 14, 2024
aa621ca
Async Locator.InnerHTML
inancgumus May 14, 2024
fb256ee
Async Locator.InnerText
inancgumus May 14, 2024
49f13fc
Async Locator.TextContent
inancgumus May 14, 2024
5016bf8
Async Locator.InputValue
inancgumus May 14, 2024
6e188c0
Async Locator.SelectOption
inancgumus May 14, 2024
4c34c82
Async Locator.Press
inancgumus May 14, 2024
b4b535b
Async Locator.Type
inancgumus May 14, 2024
fc752af
Async Locator.Hover
inancgumus May 14, 2024
eb8b802
Async Locator.DispatchEvent
inancgumus May 14, 2024
3c132e6
Async Locator.WaitFor
inancgumus May 14, 2024
fd546cb
Update TestShadowDOMAndDocumentFragment for async locator
inancgumus May 14, 2024
f7ce891
Update locator_pom.js for locator async
inancgumus May 14, 2024
d72dac2
Update locator.js for locator async
inancgumus May 14, 2024
b448a5d
Update shadowdom.js for locator async
inancgumus May 14, 2024
392ef92
Update dispatch.js for locator async
inancgumus May 14, 2024
2a517b0
Update fillform.js for locator async
inancgumus May 14, 2024
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
149 changes: 117 additions & 32 deletions browser/locator_mapping.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,16 @@ import (
)

// mapLocator API to the JS module.
func mapLocator(vu moduleVU, lo *common.Locator) mapping {
func mapLocator(vu moduleVU, lo *common.Locator) mapping { //nolint:funlen
return mapping{
"clear": func(opts goja.Value) error {
ctx := vu.Context()

"clear": func(opts goja.Value) (*goja.Promise, error) {
copts := common.NewFrameFillOptions(lo.Timeout())
if err := copts.Parse(ctx, opts); err != nil {
return fmt.Errorf("parsing clear options: %w", err)
if err := copts.Parse(vu.Context(), opts); err != nil {
return nil, fmt.Errorf("parsing clear options: %w", err)
}

return lo.Clear(copts) //nolint:wrapcheck
return k6ext.Promise(vu.Context(), func() (any, error) {
return nil, lo.Clear(copts) //nolint:wrapcheck
}), nil
},
"click": func(opts goja.Value) (*goja.Promise, error) {
popts, err := parseFrameClickOptions(vu.Context(), opts, lo.Timeout())
Expand All @@ -32,26 +31,106 @@ func mapLocator(vu moduleVU, lo *common.Locator) mapping {
return nil, lo.Click(popts) //nolint:wrapcheck
}), nil
},
"dblclick": lo.Dblclick,
"check": lo.Check,
"uncheck": lo.Uncheck,
"isChecked": lo.IsChecked,
"isEditable": lo.IsEditable,
"isEnabled": lo.IsEnabled,
"isDisabled": lo.IsDisabled,
"isVisible": lo.IsVisible,
"isHidden": lo.IsHidden,
"fill": lo.Fill,
"focus": lo.Focus,
"getAttribute": lo.GetAttribute,
"innerHTML": lo.InnerHTML,
"innerText": lo.InnerText,
"textContent": lo.TextContent,
"inputValue": lo.InputValue,
"selectOption": lo.SelectOption,
"press": lo.Press,
"type": lo.Type,
"hover": lo.Hover,
"dblclick": func(opts goja.Value) *goja.Promise {
return k6ext.Promise(vu.Context(), func() (any, error) {
return nil, lo.Dblclick(opts) //nolint:wrapcheck
})
},
"check": func(opts goja.Value) *goja.Promise {
return k6ext.Promise(vu.Context(), func() (any, error) {
return nil, lo.Check(opts) //nolint:wrapcheck
})
},
"uncheck": func(opts goja.Value) *goja.Promise {
return k6ext.Promise(vu.Context(), func() (any, error) {
return nil, lo.Uncheck(opts) //nolint:wrapcheck
})
},
"isChecked": func(opts goja.Value) *goja.Promise {
return k6ext.Promise(vu.Context(), func() (any, error) {
return lo.IsChecked(opts) //nolint:wrapcheck
})
},
"isEditable": func(opts goja.Value) *goja.Promise {
return k6ext.Promise(vu.Context(), func() (any, error) {
return lo.IsEditable(opts) //nolint:wrapcheck
})
},
"isEnabled": func(opts goja.Value) *goja.Promise {
return k6ext.Promise(vu.Context(), func() (any, error) {
return lo.IsEnabled(opts) //nolint:wrapcheck
})
},
"isDisabled": func(opts goja.Value) *goja.Promise {
return k6ext.Promise(vu.Context(), func() (any, error) {
return lo.IsDisabled(opts) //nolint:wrapcheck
})
},
"isVisible": func() *goja.Promise {
return k6ext.Promise(vu.Context(), func() (any, error) {
return lo.IsVisible() //nolint:wrapcheck
})
},
"isHidden": func() *goja.Promise {
return k6ext.Promise(vu.Context(), func() (any, error) {
return lo.IsHidden() //nolint:wrapcheck
})
},
"fill": func(value string, opts goja.Value) *goja.Promise {
return k6ext.Promise(vu.Context(), func() (any, error) {
return nil, lo.Fill(value, opts) //nolint:wrapcheck
})
},
"focus": func(opts goja.Value) *goja.Promise {
return k6ext.Promise(vu.Context(), func() (any, error) {
return nil, lo.Focus(opts) //nolint:wrapcheck
})
},
"getAttribute": func(name string, opts goja.Value) *goja.Promise {
return k6ext.Promise(vu.Context(), func() (any, error) {
return lo.GetAttribute(name, opts) //nolint:wrapcheck
})
},
"innerHTML": func(opts goja.Value) *goja.Promise {
return k6ext.Promise(vu.Context(), func() (any, error) {
return lo.InnerHTML(opts) //nolint:wrapcheck
})
},
"innerText": func(opts goja.Value) *goja.Promise {
return k6ext.Promise(vu.Context(), func() (any, error) {
return lo.InnerText(opts) //nolint:wrapcheck
})
},
"textContent": func(opts goja.Value) *goja.Promise {
return k6ext.Promise(vu.Context(), func() (any, error) {
return lo.TextContent(opts) //nolint:wrapcheck
})
},
"inputValue": func(opts goja.Value) *goja.Promise {
return k6ext.Promise(vu.Context(), func() (any, error) {
return lo.InputValue(opts) //nolint:wrapcheck
})
},
"selectOption": func(values goja.Value, opts goja.Value) *goja.Promise {
return k6ext.Promise(vu.Context(), func() (any, error) {
return lo.SelectOption(values, opts) //nolint:wrapcheck
})
},
"press": func(key string, opts goja.Value) *goja.Promise {
return k6ext.Promise(vu.Context(), func() (any, error) {
return nil, lo.Press(key, opts) //nolint:wrapcheck
})
},
"type": func(text string, opts goja.Value) *goja.Promise {
return k6ext.Promise(vu.Context(), func() (any, error) {
return nil, lo.Type(text, opts) //nolint:wrapcheck
})
},
"hover": func(opts goja.Value) *goja.Promise {
return k6ext.Promise(vu.Context(), func() (any, error) {
return nil, lo.Hover(opts) //nolint:wrapcheck
})
},
"tap": func(opts goja.Value) (*goja.Promise, error) {
copts := common.NewFrameTapOptions(lo.DefaultTimeout())
if err := copts.Parse(vu.Context(), opts); err != nil {
Expand All @@ -61,13 +140,19 @@ func mapLocator(vu moduleVU, lo *common.Locator) mapping {
return nil, lo.Tap(copts) //nolint:wrapcheck
}), nil
},
"dispatchEvent": func(typ string, eventInit, opts goja.Value) error {
"dispatchEvent": func(typ string, eventInit, opts goja.Value) (*goja.Promise, error) {
popts := common.NewFrameDispatchEventOptions(lo.DefaultTimeout())
if err := popts.Parse(vu.Context(), opts); err != nil {
return fmt.Errorf("parsing locator dispatch event options: %w", err)
return nil, fmt.Errorf("parsing locator dispatch event options: %w", err)
}
return lo.DispatchEvent(typ, exportArg(eventInit), popts) //nolint:wrapcheck
return k6ext.Promise(vu.Context(), func() (any, error) {
return nil, lo.DispatchEvent(typ, exportArg(eventInit), popts) //nolint:wrapcheck
}), nil
},
"waitFor": func(opts goja.Value) *goja.Promise {
return k6ext.Promise(vu.Context(), func() (any, error) {
return nil, lo.WaitFor(opts) //nolint:wrapcheck
})
},
"waitFor": lo.WaitFor,
}
}
10 changes: 5 additions & 5 deletions examples/dispatch.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ export default async function() {
try {
await page.goto('https://test.k6.io/', { waitUntil: 'networkidle' });

page.locator('a[href="/contacts.php"]')
.dispatchEvent("click");
const contacts = page.locator('a[href="/contacts.php"]');
await contacts.dispatchEvent("click");

check(page, {
header: (p) => p.locator("h3").textContent() == "Contact us",
});
const h3 = page.locator("h3");
const ok = await h3.textContent() == "Contact us";
check(ok, { "header": ok });
} finally {
page.close();
}
Expand Down
13 changes: 8 additions & 5 deletions examples/fillform.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,22 @@ export default async function() {
page.waitForNavigation(),
page.locator('a[href="/my_messages.php"]').click(),
]);

// Enter login credentials and login
page.locator('input[name="login"]').type('admin');
page.locator('input[name="password"]').type('123');
await page.locator('input[name="login"]').type('admin');
await page.locator('input[name="password"]').type("123");

// We expect the form submission to trigger a navigation, so to prevent a
// race condition, setup a waiter concurrently while waiting for the click
// to resolve.
await Promise.all([
page.waitForNavigation(),
page.locator('input[type="submit"]').click(),
]);
check(page, {
'header': p => p.locator('h2').textContent() == 'Welcome, admin!',
});

const h2 = page.locator('h2');
const headerOK = await h2.textContent() == 'Welcome, admin!';
check(headerOK, { 'header': headerOK });

// Check whether we receive cookies from the logged site.
check(await context.cookies(), {
Expand Down
6 changes: 3 additions & 3 deletions examples/locator.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,19 +55,19 @@ export default async function() {
page.waitForNavigation(),
tails.click(),
]);
console.log(currentBet.innerText());
console.log(await currentBet.innerText());
// the heads locator clicks on the heads button
// by using the locator's selector.
await Promise.all([
page.waitForNavigation(),
heads.click(),
]);
console.log(currentBet.innerText());
console.log(await currentBet.innerText());
await Promise.all([
page.waitForNavigation(),
tails.click(),
]);
console.log(currentBet.innerText());
console.log(await currentBet.innerText());
} finally {
page.close();
}
Expand Down
8 changes: 4 additions & 4 deletions examples/locator_pom.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,13 @@ export default async function() {
try {
await bet.goto()
await bet.tails();
console.log("Current bet:", bet.current());
console.log("Current bet:", await bet.current());
await bet.heads();
console.log("Current bet:", bet.current());
console.log("Current bet:", await bet.current());
await bet.tails();
console.log("Current bet:", bet.current());
console.log("Current bet:", await bet.current());
await bet.heads();
console.log("Current bet:", bet.current());
console.log("Current bet:", await bet.current());
} finally {
page.close();
}
Expand Down
3 changes: 2 additions & 1 deletion examples/shadowdom.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@ export default async function() {
document.body.appendChild(shadowRoot);
});
const shadowEl = page.locator("#find");
const ok = await shadowEl.innerText() === "Shadow DOM";
check(shadowEl, {
"shadow element exists": (e) => e !== null,
"shadow element text is correct": (e) => e.innerText() === "Shadow DOM",
"shadow element text is correct": () => ok,
});
page.close();
}
2 changes: 1 addition & 1 deletion tests/page_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1647,7 +1647,7 @@ func TestShadowDOMAndDocumentFragment(t *testing.T) {
p.goto("%s/%s/shadow_and_doc_frag.html")

const s = p.locator('%s')
s.waitFor({
await s.waitFor({
timeout: 1000,
state: 'attached',
});
Expand Down
Loading