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

Use async check instead of the sync one #1746

Merged
merged 15 commits into from
Sep 27, 2024
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ The script is evaluated after the document is created but before any of its scri

```javascript
import { browser } from 'k6/browser';
import { check } from 'k6';
import { check } from 'https://jslib.k6.io/k6-utils/1.5.0/index.js';

export const options = {
scenarios: {
Expand Down Expand Up @@ -63,9 +63,8 @@ export default async function () {
</script>
</html>`);

const text = await page.locator('#random').textContent();
check(page, {
zero: () => text == '0',
await check(page.locator('#random'), {
'is zero': async random => await random.textContent() == '0'
});

await page.close();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Waits for the event to fire and returns its value. If a predicate function has b
<CodeGroup labels={[]}>

```javascript
import { browser } from 'k6/x/browser';
import { browser } from 'k6/browser';

export const options = {
scenarios: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ weight: 04
## Examples

```javascript
import { check } from 'k6';
import { browser } from 'k6/browser';
import { check } from "https://jslib.k6.io/k6-utils/1.5.0/index.js";

export const options = {
scenarios: {
Expand All @@ -76,16 +76,20 @@ export default async function () {

await Promise.all([page.waitForNavigation(), messagesLink.click()]);
// Enter login credentials and login
await page.$('input[name="login"]').type('admin');
await page.$('input[name="password"]').type('123');
const login = await page.$('input[name="login"]');
await login.type('admin');
const password = await page.$('input[name="password"]');
await password.type('123');

const submitButton = await page.$('input[type="submit"]');

await Promise.all([page.waitForNavigation(), submitButton.click()]);
const text = await page.$('h2');
const content = await text.textContent();
check(page, {
header: () => text == 'Welcome, admin!',

await check(page, {
'header': async p => {
const h2 = await p.$('h2');
return await h2.textContent() == 'Welcome, admin!';
},
});
} finally {
await page.close();
Expand All @@ -97,7 +101,7 @@ export default async function () {

```javascript
import { browser } from 'k6/browser';
import { check } from 'k6';
import { check } from 'https://jslib.k6.io/k6-utils/1.5.0/index.js';

export const options = {
scenarios: {
Expand All @@ -112,7 +116,7 @@ export const options = {
},
};

export default function () {
export default async function () {
const page = await browser.newPage();

try {
Expand All @@ -128,35 +132,35 @@ export default function () {
`);

// Check state
let el = await page.$('.visible');
const isVisible = await el.isVisible();

el = await page.$('.hidden');
const isHidden = await el.isHidden();

el = await page.$('.editable');
const isEditable = await el.isEditable();

el = await page.$('.enabled');
const isEnabled = await el.isEnabled();

el = await page.$('.disabled');
const isDisabled = await el.isDisabled();

el = await page.$('.checked');
const isChecked = await el.isChecked();

el = await page.$('.unchecked');
const isUncheckedChecked = await el.isChecked();

check(page, {
visible: isVisible,
hidden: isHidden,
editable: isEditable,
enabled: isEnabled,
disabled: isDisabled,
checked: isChecked,
unchecked: isUncheckedChecked === false,
await check(page, {
'is visible': async p => {
const e = await p.$('.visible');
return e.isVisible();
},
'is hidden': async p => {
const e = await p.$('.hidden');
return e.isHidden();
},
'is editable': async p => {
const e = await p.$('.editable');
return e.isEditable();
},
'is enabled': async p => {
const e = await p.$('.enabled');
return e.isEnabled();
},
'is disabled': async p => {
const e = await p.$('.disabled');
return e.isDisabled();
},
'is checked': async p => {
const e = await p.$('.checked');
return e.isChecked();
},
'is unchecked': async p => {
const e = await p.$('.unchecked');
return await e.isChecked() === false;
},
});
} finally {
await page.close();
Expand Down
25 changes: 12 additions & 13 deletions docs/sources/next/javascript-api/k6-browser/locator/clear.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ Clears text boxes and input fields (`input`, `textarea` or `contenteditable` ele
{{< code >}}

```javascript
import { check } from 'k6';
import { browser } from 'k6/browser';
import { check } from "https://jslib.k6.io/k6-utils/1.5.0/index.js";

export const options = {
scenarios: {
Expand All @@ -49,26 +49,25 @@ export default async function () {
const context = await browser.newContext();
const page = await context.newPage();

await page.goto('https://test.k6.io/my_messages.php', { waitUntil: 'networkidle' });
await page.goto("https://test.k6.io/my_messages.php", {
waitUntil: 'networkidle',
});

// Fill an input element with some text that we will later clear
const login = page.locator('input[name="login"]');

// Fill an input element with some text that we will later clear.
await login.type('admin');

// This checks that the element has been filled with text.
let value = await login.inputValue();
check(page, {
not_empty: (p) => value != '',
// Check that the element has been filled with text
await check(login, {
'not empty': async lo => await lo.inputValue() != '',
});

// Now clear the text from the element.
// Now clear the text from the element
await login.clear();

// This checks that the element is now empty.
value = await login.inputValue();
check(page, {
empty: () => value == '',
// Check that the element is now empty
await check(login, {
empty: async lo => await lo.inputValue() == '',
});

await page.close();
Expand Down
2 changes: 1 addition & 1 deletion docs/sources/next/javascript-api/k6-browser/page/on.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ When using the `page.on` method, the page has to be explicitly [closed](https://
{{< code >}}

```javascript
import { browser } from 'k6/x/browser';
import { browser } from 'k6/browser';
import { check } from 'k6';

export const options = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ To work with the most commonly tested network profiles, import `networkProfiles`
{{< code >}}

```javascript
import { browser, networkProfiles } from 'k6/x/browser';
import { browser, networkProfiles } from 'k6/browser';

export const options = {
scenarios: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Returns when the `pageFunction` returns a truthy value.

```javascript
import { browser } from 'k6/browser';
import { check } from 'k6';
import { check } from 'https://jslib.k6.io/k6-utils/1.5.0/index.js';

export const options = {
scenarios: {
Expand Down Expand Up @@ -64,8 +64,10 @@ export default async function () {
polling: 'mutation',
timeout: 2000,
});
const innerHTML = await ok.innerHTML();
check(ok, { 'waitForFunction successfully resolved': innerHTML == 'Hello' });
await check(ok, {
'waitForFunction successfully resolved': async (ok) =>
await ok.innerHTML() == 'Hello'
});
} finally {
await page.close();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ Events can be either:
{{< code >}}

```javascript
import { check } from 'k6';
import { browser } from 'k6/browser';
import { check } from 'https://jslib.k6.io/k6-utils/1.5.0/index.js';

export const options = {
scenarios: {
Expand All @@ -65,7 +65,7 @@ export const options = {
};

export default async function () {
const page = await browser.newPage();
let page = await browser.newPage();

try {
await page.goto('https://test.k6.io/my_messages.php');
Expand All @@ -76,11 +76,10 @@ export default async function () {
const submitButton = page.locator('input[type="submit"]');
await submitButton.click();

await page.waitForLoadState(); // waits for the default `load` event
await page.waitForLoadState('networkidle'); // waits until the `networkidle` event

const text = await page.locator('h2').textContent();
check(page, {
header: () => text == 'Welcome, admin!',
await check(page.locator('h2'), {
'header': async h2 => await h2.textContent() == 'Welcome, admin!'
});
} finally {
await page.close();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ Events can be either:
{{< code >}}

```javascript
import { check } from 'k6';
import { browser } from 'k6/browser';
import { check } from 'https://jslib.k6.io/k6-utils/1.5.0/index.js';

export const options = {
scenarios: {
Expand All @@ -69,11 +69,13 @@ export default async function () {

const submitButton = page.locator('input[type="submit"]');

await Promise.all([page.waitForNavigation(), submitButton.click()]);
await Promise.all([
submitButton.click(),
page.waitForNavigation(),
]);

const text = await page.locator('h2').textContent();
check(page, {
header: () => text == 'Welcome, admin!',
await check(page.locator('h2'), {
header: async h2 => await h2.textContent() == 'Welcome, admin!'
});
} finally {
await page.close();
Expand Down
7 changes: 3 additions & 4 deletions docs/sources/next/using-k6-browser/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ The main use case for the browser module is to test performance on the browser l

```javascript
import { browser } from 'k6/browser';
import { check } from 'k6';
import { check } from 'https://jslib.k6.io/k6-utils/1.5.0/index.js';

export const options = {
scenarios: {
Expand Down Expand Up @@ -68,9 +68,8 @@ export default async function () {
page.locator('input[type="submit"]').click(),
]);

const header = await page.locator("h2").textContent();
check(header, {
header: (h) => h == "Welcome, admin!",
await check(page.locator("h2"), {
'header': async h2 => await h2.textContent() == "Welcome, admin!"
});
} finally {
await page.close();
Expand Down
17 changes: 10 additions & 7 deletions docs/sources/next/using-k6-browser/migrating-to-k6-v0-52.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ This guide outlines the key changes you will need to make when moving your exist
In the latest release of k6, we have graduated k6 browser module out of experimental and is now under the import `k6/browser`. Migrating to this is a breaking change that will affect _all scripts_ that use the experimental k6 browser module. The breaking changes are:

1. Converted most of the k6 browser module APIs to asynchronous (async) APIs. That means they will return a `promise` that will `resolve` to a value when the API call succeeds or `reject` when an error occurs.
2. A side effect of making this async changes is that you will need to use a workaround to work with the k6 [check](http://grafana.com/docs/k6/<K6_VERSION>/javascript-api/k6/check/) API.
2. A side effect of making this async changes is that you will need to use [the `check` utility function from jslib.k6.io](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/jslib/utils/check/) instead of working with the k6 [check](http://grafana.com/docs/k6/<K6_VERSION>/javascript-api/k6/check/) API.
3. Finally, it's also worth reiterating that the [group](http://grafana.com/docs/k6/<K6_VERSION>/javascript-api/k6/group/) API still doesn't work with async APIs.

If you are interested in the rationale behind this change, refer to the [v0.51 release notes](https://github.com/grafana/k6/releases/tag/v0.51.0).
Expand Down Expand Up @@ -275,7 +275,7 @@ Below is a screenshot of a comparison between a generic browser test in `v0.51`

## Working with k6 check

The k6 `check` API will not `await` promises, so calling a function that returns a `Promise`, for example `locator.textContent()`, inside one of the predicates will not work. Instead you will have to `await` and store the result in a variable _outside_ the `check`:
The k6 `check` API will not `await` promises, so calling a function that returns a `Promise`, for example `locator.textContent()`, inside one of the predicates will not work. Instead, you can work with [the jslib.k6.io's `check` utility function](https://grafana.com/docs/k6/latest/javascript-api/jslib/utils/check/).

For example, before:

Expand All @@ -284,8 +284,8 @@ For example, before:
<!-- eslint-skip -->

```javascript
check(page, {
header: (p) => p.locator('h2').textContent() == 'Welcome, admin!',
check(page.locator('h2'), {
header: lo => lo.textContent() == 'Welcome, admin!',
});
```

Expand All @@ -298,9 +298,12 @@ And now:
<!-- eslint-skip -->

```javascript
const headerText = await page.locator('h2').textContent();
check(headerText, {
header: headerText === 'Welcome, admin!',
import { check } from 'https://jslib.k6.io/k6-utils/1.5.0/index.js';

// ...

await check(page.locator('h2'), {
'header': async lo => await lo.textContent() === 'Welcome, admin!'
});
```

Expand Down
Loading
Loading