How to keep the browser open?

Hey folks, nice to meet you.

I have written a simple test with K6 browser – it logs into a website and then brings up a sequential series of pages.

It seems to work, but no matter what I do the browser closes at 30 seconds, causing all remaining actions to fail. I’ve spent time searching on the web and in the documentation, and I haven’t figured out a way around it. Perhaps it is related to the gracefulStop parameter, but it complains about an unknown option when placed in options.

I’m sure there is something very silly that I’m overlooking, but I’ve been banging my head against this for several hours and have not made any progress.

Thanks in advance for any assistance that can be offered!

BTW, it does not appear to be related to gracefulStop. I increased it with this:

  scenarios: {
    test: {
      executor: 'constant-vus',
      vus: 1,
      duration: '100s',
      gracefulStop: '60s',
    },
  },
};

and while it now reports as a minute, the browser still closes precisely at 30 seconds.

Hi @mcw

It could be issue with the script, where it not able to perform some action or page is not completely loaded.

you can add some wait there e.g. sleep(30) or page.waitForNavigation() before performing the step where its failing

It is definitely a timing issue, because it will fail in different places, but always exactly at 30 seconds.

If I change the order of the pages that are loaded, the one that fails will be the one that’s up when the script has been running for 30 seconds.

It’s just a long chain of promises, and I’ve tried reordering. That’s how I figured out it was a timing issue and not something specific to a page:

 page
    .goto(`${host_port}${url}`, { waitUntil: "networkidle" })
    .then(() => {
      page.locator('input[name="inputusername"]').type(username);
      page.locator('input[name="inputpassword"]').type([password]);
      page.screenshot({ path: "login-screenshot.png" });
      page.locator('//button[text()=" Login"]').click();
    })
    .then(() => {
      url = "/r/apps/assets";
      console.log(`Bringing up ${url}`);
      page.goto(`${host_port}${url}`, { waitUntil: "networkidle" });
      sleep(page_load_wait);
      page.screenshot({ path: "assets-screenshot.png" });
    })
    .then(() => {
      url = "/r/apps/assessments";
      console.log(`Bringing up ${url}`);
      page.goto(`${host_port}${url}`, { waitUntil: "networkidle" });
      sleep(page_load_wait);
      page.screenshot({ path: "assessments-screenshot.png" });
    })
    .then(() => {
      url = "/r/apps/incidents";
      console.log(`Bringing up ${url}`);
      page.goto(`${host_port}${url}`, { waitUntil: "networkidle" });
      sleep(page_load_wait);
      page.screenshot({ path: "incidents-screenshot.png" });
    })

I’ve tried setting all the timings that I can think of, but to no avail…

  const context = browser.newContext();
  context.setDefaultNavigationTimeout(120000);
  context.setDefaultTimeout(120000);

Hi @mcw

Can you try returning promise after clicking on login. I have written script as below and it works-

export function webtest() {
  const browser = chromium.launch({
    args: [],                   // Extra commandline arguments to include when launching browser process
    debug: true,                // Log all CDP messages to k6 logging subsystem
    devtools: true,             // Open up developer tools in the browser by default
    env: {},                    // Environment variables to set before launching browser process
    executablePath: null,       // Override search for browser executable in favor of specified absolute path
    headless: true,            // Show browser UI or not
    ignoreDefaultArgs: [],      // Ignore any of the default arguments included when launching browser process
    proxy: {},                  // Specify to set browser's proxy config
    slowMo: '1000ms',            // Slow down input actions and navigations by specified time
    timeout: '60s',             // Default timeout to use for various actions and navigations
  });
  const page = browser.newPage();
  page.goto(Utils.getBaseUrl() , { waitUntil: 'load' }).
    then(() => {
      page.locator(selectors.loginPage.username).type('')
      page.locator(selectors.loginPage.password).type('')
      return Promise.all([
        page.waitForNavigation(),
        page.locator(loginBtn).click()
      ]).then(() => {
        page.screenshot({ path: 'screenshots/01_login.png' }),
          page.waitForSelector(""),
          page.locator("").type('')
        page.waitForSelector('')
        return Promise.all([
          page.waitForNavigation(),
          page.locator("").click()
        ])
      }).then(() => {
        page.waitForSelector(""),
          check(page, {
            'Patient Page': page.locator("").textContent() == '',
          });
        page.screenshot({ path: 'screenshots/02.png' })
      }).finally(() => {
        page.close();
        browser.close();
      })
    })

@vish_s02 – thanks for your input!

I’m a backend developer – not a front end one – but I think I’ve done what you’ve suggested, and the browser is still always forcibly closing at 30 seconds. (In fact, things seems to get a little worse, in that the script stops loading pages after the third one and just waits for the forcible close!)

Has anyone seen a browser stay up longer than a 30 second run time? If so, would they be willing to share the script?

  page
    .goto(`${host_port}${url}`, { waitUntil: "networkidle" })
    .then(() => {
      return Promise.all([
        page.locator('input[name="inputusername"]').type(username),
        page.locator('input[name="inputpassword"]').type([password]),
        page.screenshot({ path: "login-screenshot.png" }),
        page.waitForNavigation(),
        page.locator('//button[text()=" Login"]').click(),
      ]);
    })
    .then(() => {
      url = "/r/apps/assets";
      console.log(`Bringing up ${url}`);
      return Promise.all([
        page.goto(`${host_port}${url}`, { waitUntil: "networkidle" }),
        sleep(page_load_wait),
        page.screenshot({ path: "assets-screenshot.png" }),
      ]);
    })
    .then(() => {

Hi @mcw

Can you have one more try, seems you havnt return promise at correct place

export function webtest() {
  const browser = chromium.launch({
    args: [],                   // Extra commandline arguments to include when launching browser process
    debug: true,                // Log all CDP messages to k6 logging subsystem
    devtools: true,             // Open up developer tools in the browser by default
    env: {},                    // Environment variables to set before launching browser process
    executablePath: null,       // Override search for browser executable in favor of specified absolute path
    headless: true,            // Show browser UI or not
    ignoreDefaultArgs: [],      // Ignore any of the default arguments included when launching browser process
    proxy: {},                  // Specify to set browser's proxy config
    slowMo: '1000ms',            // Slow down input actions and navigations by specified time
    timeout: '60s',             // Default timeout to use for various actions and navigations
  });
  const page = browser.newPage();
  page
    .goto(`${host_port}${url}`, { waitUntil: "networkidle" })
    .then(() => {
      page.locator('input[name="inputusername"]').type(username),
        page.locator('input[name="inputpassword"]').type([password]),
        page.screenshot({ path: "login-screenshot.png" })
      return Promise.all([
        page.waitForNavigation(),
        page.locator('//button[text()=" Login"]').click(),
      ]).then(() => {
        url = "/r/apps/assets";
        console.log(`Bringing up ${url}`);
        page.goto(`${host_port}${url}`, { waitUntil: "networkidle" })
          .then(() => {
            page.screenshot({ path: "assets-screenshot.png" })
          })
      }).then(() => {
        url = "/r/apps/assets";
        console.log(`Bringing up ${url}`);
        page.goto(`${host_port}${url}`, { waitUntil: "networkidle" })
          .then(() => {
            page.screenshot({ path: "assets-screenshot.png" })
          })
      }).finally(() => {
        page.close();
        browser.close();
      })
    })

Welcome @mcw,

What error are you seeing? Could you paste the full terminal output?

Cheers,
Ankur

EDIT: If you are testing a publicly accessible website, could you paste the link to it too?