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

Add a migration guide for k6 browser v0.52 #1604

Merged
merged 19 commits into from
Jun 5, 2024

Conversation

ankur22
Copy link
Contributor

@ankur22 ankur22 commented Jun 4, 2024

What?

This migration guide is to be published asap so that we can start to direct users/customers to this page to allow them to make changes to their scripts to future proof them for the upcoming breaking change in v0.52 of k6.

Checklist

  • I have used a meaningful title for the PR.
  • I have described the changes I've made in the "What?" section above.
  • I have performed a self-review of my changes.
  • I have run the npm start command locally and verified that the changes look good.
  • I have made my changes in the docs/sources/next folder of the documentation.
  • I have reflected my changes in the docs/sources/v{most_recent_release} folder of the documentation.
  • I have reflected my changes in the relevant folders of the two previous k6 versions of the documentation (if still applicable to previous versions).

Related PR(s)/Issue(s)

#1600
grafana/xk6-browser#428
#1607

@ankur22 ankur22 requested a review from heitortsergent as a code owner June 4, 2024 14:44
@ankur22 ankur22 marked this pull request as draft June 4, 2024 14:44
@@ -0,0 +1,215 @@
---
Copy link
Contributor Author

@ankur22 ankur22 Jun 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This page will be published under the current release (v0.51). Once this page has been approved, I'll clone the approved page, and make the necessary amendments to it for the next release (v0.52).

EDIT: The PR for the same doc for the next release is in #1607.

Copy link
Member

@inancgumus inancgumus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! Thanks. Some suggestions (no strong opinions).


You will likely already have encountered async APIs when working with the browser module such as [page.click]({{< relref "../javascript-api/k6-experimental/browser/page/click/" >}}), so the use of `async` and `await` keywords will be familiar to you.

The full list of APIs that will migrate over to be async can be found in this [github comment](https://github.com/grafana/xk6-browser/issues/428#issuecomment-1964020837). You will also find a screenshot of a comparison between the [fillform.js example](https://github.com/grafana/xk6-browser/blob/main/examples/fillform.js) in `v0.51` and `v0.52` in another [comment](https://github.com/grafana/xk6-browser/issues/428#issuecomment-2141634960) in the same github issue.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would put that list and image here in this migration document for immediate visibility instead of linking it to a comment on a Github issue.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good spot, i was supposed to put a comment here asking for suggestions on this.

@heitortsergent what's the best way to add this very long list to the docs? Is it possible to have a collapsible list?

I'm assuming the image is straight forward. However it would be better if there is already a built in code comparison view?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added the full list of APIs in 7b5f2d7

I've added a new screenshot comparing a simpler example script in 410edd5

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've found a way to collapse long lists.


# Are there any other upcoming major breaking changes?

We think that this is likely the last large breaking change until the browser module is deemed to be stable enough to be a non-experimental module in k6. When the browser module is no longer experimental, we think it should only be a small change in the import path from `k6/experimental/browser` to `k6/browser`. We have an open [issue on github](https://github.com/grafana/xk6-browser/issues/1117) which you can view and track to see the progress of graduating the browser module out of experimental. For more information on graduating extension out of experimental, refer to the [extension graduation process]({{< relref "../extensions/explanations/extension-graduation" >}}).
Copy link
Member

@inancgumus inancgumus Jun 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wouldn't link to the non-experimental issue just yet because most of its tasks have not been completed yet, and the issue strongly points out that the module is not stable, etc. Although we're at an experimental stage, I wouldn't directly advertise it like so. Users might incorrectly decide that it's not yet safe to use this module.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, yep, I see what you are saying, and it's not particularly user friendly. I was trying to emphasis that this was seriously on the cards and people should be ready for another possible breaking change. At the same time, this could dissuade users from even trying to work with k6 browser if they saw this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed in 4978eeb


### When can I migrate?

Awaiting on something that’s not a thenable just returns that value. In another words, you can add the `await` keyword today to the browser module API calls in your scripts to future proof them. For example this works in k6 `v0.51` and it will work in k6 `v0.52`:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"It is safe to add the await keyword in front of the methods to be ready for the upcoming changes..."?

Copy link
Contributor Author

@ankur22 ankur22 Jun 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Awaiting on something that’s not a thenable just returns that value. In another words, you can add the `await` keyword today to the browser module API calls in your scripts to future proof them. For example this works in k6 `v0.51` and it will work in k6 `v0.52`:
Awaiting on something that’s not a thenable just returns that value. In another words, it is safe to add the `await` keyword in front of the browser module API methods in your existing scripts to be ready for the upcoming changes. For example this works in k6 `v0.51` and it will work in k6 `v0.52`:

WDYT?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Amended in 5399033

@ankur22 ankur22 marked this pull request as ready for review June 4, 2024 16:24
Comment on lines 203 to 205
## Groups

A note on groups, they do not work with async APIs either, there is no workaround as of yet. Here's the [github issue](https://github.com/grafana/k6/issues/2728) that you can follow to keep up to date with relevant news on a groups API that works with async APIs.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it worth mentioning this? It's likely that people have already tried this and realised that it doesn't work since a group might contain a page.goto or page.click API call, which are both async already.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My two cents, I think it's worth adding it here just to be explicit that this is a limitation. It could save someone time versus discovering it on their own.


We will also be releasing the latest type definitions and updating the documentation when we release k6 `v0.52`. Refer to the [k6 IntelliSense]({{< relref "../set-up/configure-k6-intellisense" >}}) documentation on how to work with the type definition file in your project.

For all the details, make sure to review the **upcoming** changelog for [k6 version 0.52](https://github.com/grafana/k6/releases/tag/v0.52.0). As always, ask in [the community forum](https://community.grafana.com/c/grafana-k6/k6-browser/79) if you need help!
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should I remove the link to the missing release notes file for now?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I wouldn't add a missing link here. I think we could change it to:

Suggested change
For all the details, make sure to review the **upcoming** changelog for [k6 version 0.52](https://github.com/grafana/k6/releases/tag/v0.52.0). As always, ask in [the community forum](https://community.grafana.com/c/grafana-k6/k6-browser/79) if you need help!
For all the details, make sure to review the _upcoming_ CHANGELOG for [k6 version 0.52](https://github.com/grafana/k6/releases/). You can also ask questions in [the community forum](https://community.grafana.com/c/grafana-k6/k6-browser/79) if you need help.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! I've added this suggestion and also all the suggestions from #1606

@ankur22 ankur22 force-pushed the add/k6-browser-async-migration branch 2 times, most recently from 7ac72bc to 7333012 Compare June 5, 2024 08:44
Copy link
Collaborator

@allansson allansson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for being a bit late to the party. Added a few comments with some suggestions.

Comment on lines 118 to 120
### Can I promise chain in v0.51?

If you want to promise chain the newly migrated async APIs, You won't be able to do that until after the migration and release of k6 `v0.52`. For example, you can't do this yet:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
### Can I promise chain in v0.51?
If you want to promise chain the newly migrated async APIs, You won't be able to do that until after the migration and release of k6 `v0.52`. For example, you can't do this yet:
### Can I chain promises in v0.51?
No. If you want to chain promises using the `then`, `catch` and `finally` methods, you will have wait until after the release of k6 `v0.52`. Using the `await` keyword will not transform the returned value into a `Promise` that has those methods.
For example, you can't do this yet:

I have a few suggestions here.

First, I think it's a good idea to give a direct answer to the question: "No.". For some readers that might be enough and they can skip past the rest. For others, it sets the expectation of the rest of the answer and helps the reader interpret it in a correct way.

Then I changed from the noun "promise chain" to the verb form "to chain promises" and tried to put into words what that means and why it won't work.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the feedback, what about this: f739cec

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! I would still prefer a . instead of , after the "No" though. 🙂

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Amended in ee78bc5

Comment on lines 167 to 366
The k6 `check` API wasn't designed to work with async APIs. However there is a workaround. In your current scripts, you may have used a `check` like so:

{{< code >}}

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

// options block

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

// ...

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

// ...
}
```

{{< /code >}}

Since the `locator.textContent` API is being migrated to async, and `check` doesn't work with async APIs, you will need to do something like this:

{{< code >}}

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

// options block

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

// ...

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

// ...
}
```

{{< /code >}}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The k6 `check` API wasn't designed to work with async APIs. However there is a workaround. In your current scripts, you may have used a `check` like so:
{{< code >}}
```javascript
import { browser } from 'k6/experimental/browser';
import { check } from 'k6';
// options block
export default async function () {
const page = browser.newPage();
// ...
check(page, {
header: (p) => p.locator('h2').textContent() == 'Welcome, admin!',
});
// ...
}
```
{{< /code >}}
Since the `locator.textContent` API is being migrated to async, and `check` doesn't work with async APIs, you will need to do something like this:
{{< code >}}
```javascript
import { browser } from 'k6/experimental/browser';
import { check } from 'k6';
// options block
export default async function () {
const page = browser.newPage();
// ...
const h2 = page.locator('h2');
const headerOK = (await h2.textContent()) == 'Welcome, admin!';
check(headerOK, { header: headerOK });
// ...
}
```
{{< /code >}}
The k6 `check` API will not `await` promises, so calling a function that returns a `Promise`, e.g. `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`, like so:
{{< code >}}
```javascript
// Before
check(page, {
header: (p) => p.locator('h2').textContent() == 'Welcome, admin!',
});
// After
const headerText = await page.locator('h2').textContent();
check(headerText, {
header: text === 'Welcome, admin!'
});
{{< /code >}}

I found it hard to see what I would actually have to change to make my code work. I condensed it down to only include the affected parts, made sure that they looked as similar as possible and put them next to each other in the same snippet so that it's easier to see the difference.

I also tried to explain why it's problematic and what they need to do.

WDYT?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like it. The issue is with the linter, it complains that check, page etc aren't defined in the example. I've amended your example a tiny bit to avoid the linter issue. Updated in 38cf3a1.

@heitortsergent is there a way to bypass the javascript linter?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found a way to skip the linter.

Copy link
Member

@inancgumus inancgumus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work 🎉 🙇

ankur22 and others added 16 commits June 5, 2024 17:00
This migration guide is to be published asap so that we can start to
direct users/customers to this page to allow them to make changes to
their scripts to future proof them for the upcoming breaking change in
v0.52 of k6.
Co-authored-by: İnanç Gümüş <[email protected]>
This should help users know that we've removed the parts of the code to
help focus on the most important aspects of the code in the example.
Co-authored-by:  Heitor Tashiro Sergent <[email protected]>
@ankur22 ankur22 force-pushed the add/k6-browser-async-migration branch from c3396c3 to e424f83 Compare June 5, 2024 16:00
@ankur22 ankur22 merged commit 13b4c67 into main Jun 5, 2024
4 checks passed
@ankur22 ankur22 deleted the add/k6-browser-async-migration branch June 5, 2024 16:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants