Skip to main content

Writing A Scenario

To estimate the carbon footprint of your application, GreenFrame executes a Playwright scenario in a sandboxed container.

Your First Scenario#

Create a JS file named as you whish - for instance scenario.js. It should contain an async function expecting one argument: a page object.

./scenario.js
async function(page) {
// Here interactions using the page object
}

Then, write user interactions as calls to the page object method. Every interaction returns a promise, so be be sure to await them to run the scenario step by step.

Here is an example scenario:

./scenario.js
async (page) => {
await page.goto("", { waitUntil: "networkidle" }); // Go to the baseUrl
await page.waitForTimeout(3000); // Wait for 3 seconds
await page.scrollToElement("footer"); // Scroll to the footer (if present)
await page.waitForNetworkIdle(); // Wait every request has been answered as a normal user.
};

Custom Playwright Instance#

GreenFrame's Playwright instance is tweaked in 2 ways:

  • To better replicate real user interactions (which are much slower than what a robot does), new methods were added and some existing methods were overridden.
  • To prevent malicious users from executing arbitrary shell scripts in the container, some methods were removed

Page Methods#

GreenFrame exposes the same methods as Playwright's through its page object. Moreover, we've added some new methods to improve dev experience.

Here is a list of methods that only exists in GreenFrame's page object.

page.scrollToElement(selector)#

Scroll smoothly to an element.

Example:

await page.scrollToElement("footer");

page.waitForNetworkIdle([state, options])#

This method wait until networkIdle.

  • This is syntactic sugar for page.waitForLoadState() where the state is fixed at networkidle

Playwright doc

await page.waitForNetworkIdle(); // The promise resolves after 'networkidle' event.
]);

page.scrollByDistance(distance)#

Scroll smoothly by given offset in pixels

  • distance <number>: Distance of the smooth scroll. Can either be positive (go down) or negative (go up).

Example:

await page.scrollByDistance(100); // go down by 100px
await page.scrollByDistance(-100); // go up by 100px

page.addMilestone(milestone)#

During an analysis, you can add milestones on your scenario. Theses milestones will be displayed on analysis graphs and allow you to understand which user actions perform this peak on graphs.

Example:

await page.addMilestone("Go to home");

The milestone name must be unique in your scenario.

Best practices to write a good scenario#

To have a good stability on your scenario and detect changes during your development, it is important to keep in mind some best practices by using GreenFrame CLI. The main goal is to be sure that GreenFrame CLI will tracks every network request, every page rendering and will collects the same amount of data for each subsequent analyses.

Typically, if you click on a button while the server as not responded to the request yet, GreenFrame CLI might doesn't track the entire networks traffic.

If your page hasn't been entirely loaded, your CPU Usage will also be underestimated.

Use { waitUntil: 'networkidle' } as often as possible#

Avoid :

await page.goto("/path");
await page.waitForNavigation();

Prefer:

await page.goto("/path", { waitUntil: "networkidle" });
await page.waitForNavigation({ waitUntil: "networkidle" });

By default a goto function will be resolved when the page has fired the load event.

The waitUntil with networkidle option force Playwright to resolve the function when no request has been opened in the last 500ms and all requests have been answered.

Whenever you want to be sure your network has been fully tracked, you can use the following custom function:

await page.waitForNetworkIdle();

Use waitForNavigation on page change#

Most of the time your scenario will click on a button or a link to be redirected to another page. You can ensure that your navigation is terminated by using a Promise.all()

await Promise.all([
page.waitForNavigation({ waitUntil: "networkidle" }),
page.click("a"),
]);

The following line will be resolved when both waitForNavigation and click function have been resolved. It is important to put in first the waitForNavigation function because it will tell to Playwright to be ready for a page change.