Hello, dear k6 community!
I’m recently joined on the board and I glad to use this framework for daily performancre testing.
At the moment I have one question, that I can’t resolve on my own. I would grateful to some advice from developers or more experienced user than I am.
Question is next:
I created simple scenario like this:
import { chromium } from 'k6/x/browser';
import { sleep } from 'k6';
export const options = {
scenarios: {
go_to_statistics_page: {
tags: { name: 'statistics'},
executor: 'constant-vus',
exec: 'go_to_statistics_page',
vus: 1,
iterations: '1',
maxDuration: '30s',
startTime: '0s',
gracefulStop: '10s'
},
go_to_incidents_archive_page: {
tags: { name: 'incidents_archive_page'},
executor: 'constant-vus',
exec: 'go_to_incidents_archive_page',
vus: 1,
maxDuration: '30s',
iterations: '1',
startTime: '80s',
gracefulStop: '40s'
},
and more similar tests in this scenario
examples of tests function are represented below:
export function go_to_statistics_page() {
const browser = chromium.launch({ args: ['no-sandbox', 'remote-debugging-port=9223'], headless:
true, timeout: '5m', });
const context = browser.newContext({ ignoreHTTPSErrors: true, })
const page = context.newPage();
page.goto('https://' + __ENV.SENSOR_IP + '/#/login');
page.waitForSelector("#e-login-page_login");
page.type("#e-login-page_login", "Administrator");
page.waitForSelector("#e-login-page_password");
page.type("#e-login-page_password", "P@ssw0rd");
page.waitForSelector("button#e-login-page_login-button");
page.locator("button#e-login-page_login-button").click();
page,goto('https://' + __ENV.SENSOR_IP +
'/#/main/r/dashboard;type=preset;interval=5;autoupdate=true')
page.waitForSelector("//span[contains(text(), ' Incident severity levels '), {visible: true, 'timeout': 30000})]
console.log("Statistics Page is opened")
page.close();
browser.close();
};
export function go_to_incidents_archive_page() {
const browser = chromium.launch({ args: ['no-sandbox', 'remote-debugging-port=9223'], headless:
true, timeout: '5m', });
const context = browser.newContext({ ignoreHTTPSErrors: true, })
const page = context.newPage();
page.goto('https://' + __ENV.SENSOR_IP + '/#/login');
page.waitForSelector("#e-login-page_login");
page.type("#e-login-page_login", "Administrator");
page.waitForSelector("#e-login-page_password");
page.type("#e-login-page_password", "P@ssw0rd");
page.waitForSelector("button#e-login-page_login-button");
page.locator("button#e-login-page_login-button").click();
page.goto('https://' + __ENV.SENSOR_IP + '/#/main/r/incidents/archive')
page.waitForSelector("//div[@class='ag-center-cols-viewport' and @ref='eCenterViewport']",
{'visible': true, 'timeout': 30000});
console.log("Incidents Page is opened")
page.close();
browser.close();
};
As you can see tests have repetitive actions of creating new browser instance and login that i would like to reduce and use them only once before all tests.
What I tried to resolve it:
- It’s apparently to insert in the script setup() function and make login inside of it and then return browser instance to tests.
export function setup() {
let login = "Administrator";
let password = "P@ssw0rd";
const browser = chromium.launch({ args: ['no-sandbox', 'remote-debugging-port=9223'], headless:
true, timeout: '5m', });
const context = browser.newContext({ ignoreHTTPSErrors: true, })
const page = context.newPage();
page.goto('https://' + __ENV.SENSOR_IP + '/#/login').then(() => {
page.waitForSelector('#e-login-page_login');
page.type("#e-login-page_login", login);
page.waitForSelector("#e-login-page_password");
page.type("#e-login-page_password", password);
return page.click('button#e-login-page_login-button');
}).then(() => {
page.screenshot({ path: 'screenshots/login' });
}).finally(() => {
page.close();
browser.close();
});
};
But when I try to reuse instance of browser from setuo() in tests I find that setupData is empty: {}
export function go_to_statistics_page(setupData) {
console.log(setupData)
}
- Also I tried to use predefined persistent context, that was created from another script.
I found that there is issue on Github: Implement BrowserType.launchPersistentContext(userDataDir[, options]), that’s why
I created persistent context with another (not k6) JS-script:
import playwright from 'playwright';
import { test, expect } from '@playwright/test';
import os from 'os';
import fs from 'fs';
import path from 'path';
(async () => {
const userDataDir = path.join(os.tmpdir(), 'browser-context', String('any-test'));
const context = await playwright['chromium'].launchPersistentContext(userDataDir, { args: ['--remote-debugging-port=9222'], headless: true, ignoreHTTPSErrors: true });
const page = await context.newPage();
await page.goto('http://SENSOR_IP/#/login');
await page.locator("id=e-login-page_login").fill('Administrator');
await page.locator("id=e-login-page_password").fill('P@ssw0rd');
await page.locator("id=e-login-page_login-button").click();
await context.close();
})();
And then I tried to reuse it in k6 chromium launch :
import { chromium } from 'k6/x/browser';
export default function go_to_incidents_archive_page() {
const browser = chromium.launch({ args: ['no-sandbox', 'remote-debugging-port=9223', "user-data-
dir=/tmp/browser-context/any-test/"], headless:
true, timeout: '5m', });
const page = browser.newPage({ ignoreHTTPSErrors: true, });
page.goto('https://' + __ENV.SENSOR_IP + '/#/main/r/incidents/archive');
But in this case it seems browser ignores ‘user-data-dir’ and doesn’t use provided profile, because it still appears on login page and does’t go to required URL
Maybe someone has already encountered such a problem and knows a way to solve it.
Sorry if my question is too long for reading, I tried to explain the problem in detail.
Thank you for advance!
Additionally my k6 environment is:
k6 v0.43.1 ((devel), go1.19.9, linux/amd64)
Extensions:
GitHub - grafana/xk6-browser: k6 extension that adds support for browser automation and end-to-end web testing via the Chrome Devtools Protocol v0.9.0, k6/x/browser [js]