Deploy Your Tests

You’re ready to deploy automated tests! That’s amazing. You’re ahead of 90% of devs on the planet.

This article will show you how to deploy your tests to BrowserCat, saving you time, money, and headaches. No longer will your CI/CD pipeline take longer than Hibachi lunch. Get used to scarfing down a taco between deploys.

Deploy your tests

Playwright is often billed as an e2e testing library. But it can be used for much more than that. During CI/CD not only can you run limited e2e tests, but you can also directly test your staging or production environments and trigger rollbacks if anything goes wrong.

Similarly, you can also consider running your tests against production as an hourly job to ensure that none of your upstream dependencies have broken your app. This is especially useful if you’re building functionality on top of browser automation scripts, which are subject to potential changes.

Whatever kind of testing you’re interested, the process for leveraging BrowserCat’s fleet of headless browsers remains the same.

Let’s get you up and running!

Connect to a remote browser

If you followed the instructions in “Your First Test,” you probably don’t yet have a config file for your tests. Let’s create one now.

Fist, create the file:

touch playwright.config.ts
# Currently unsupported (see above)

Then add the following:

import {defineConfig} from '@playwright/test';

const bcatUrl = 'wss://api.browsercat.com/connect';
const bcatKey = '<YOUR API KEY>';

export default defineConfig({
  use: {
    connectOptions: {
      wsEndpoint: bcatUrl,
      headers: {'Api-Key': bcatKey},
    },
  },
});
# Currently unsupported (see above)

If you run your tests now, they should connect to BrowserCat’s fleet of headless browsers.

Working with local servers

Typically, devs will run tests against locally running servers, whether during local development or within CI/CD pipelines. However, in both of these cases, BrowserCat’s browser fleet will not be able to access the servers in question.

While we strongly recommend running your CI/CD tests against a fully deployed staging environment (because it more closely mirrors production), we understand that this isn’t always possible.

Let’s talk through two solutions for working with local servers…

1. Configure environments differently

One alternative is to configure your local tests differently from tests that run against staging or production.

At BrowserCat, we leverage this solution. Our local tests run against a local server, while our CI/CD tests run against a staging server.

To do so, we’ll lean on Playwright’s “projects” feature. This allows us trigger different test suites with a single CLI flag.

Let’s update our config file:

import {defineConfig} from '@playwright/test';

const bcatUrl = 'wss://api.browsercat.com/connect';
const bcatKey = '<YOUR API KEY>';

export default defineConfig({
  projects: [
    {
      name: 'local',
      use: {
        baseURL: 'http://localhost:3000',
      },
    },
    {
      name: 'staging',
      use: {
        baseURL: 'https://staging.example.com',
        connectOptions: {
          wsEndpoint: bcatUrl,
          headers: {'Api-Key': bcatKey},
        },
      },
    },
  ],
});
# Currently unsupported (see above)

As you can see above, we now have two projects: local and staging. The former will run against a local server, while the latter will run against BrowserCat’s fleet.

Be warned! By default, Playwright will run all projects. In order to specify which project to run, you’ll need to pass the --project flag to the CLI:

npx playwright test --project=local
npx playwright test --project=staging
# Currently unsupported (see above)

Now you can leverage the full power of working with headless browsers locally while easily triggering staging (or production) tests against BrowserCat’s fleet.

2. Expose a local port

If you don’t mind the overhead of running headless browsers locally, the above solution works wonderfully. However, many users will still want to speed up their local and CI/CD tests without having to deploy to staging.

If this is you, you’re best bet will be to temporarily expose a local port to the internet. This will allow BrowserCat’s fleet to access your local server.

There are a number of ways to do this. Here are just a few:

  • serveo - fast, light, and easy
  • ngrok - great features, but requires an account
  • VS Code - built-in and free, but requires a GUI

Because of it’s simplicity, we’ll use “serveo” for this example. We’ll first generate a unique subdomain, then will expose our local port using that subdomain, and finally, we’ll pass exposed URL into our tests as an environment variable.

# Generate a unique subdomain
export FWD=$(openssl rand -hex 4).serveo.net

# Expose our local port
ssh -R $FWD:80:localhost:3000 serveo.net

# Run our tests
BASE_URL=$FWD npx playwright test --project=staging
# Currently unsupported (see above)

Now you can run your tests against your local server, but with the speed and scale of BrowserCat’s fleet.

Maximize concurrency

Playwright typically limits concurrency. On a normal machine, it defaults to parallelizing to half the number of CPU cores. And in CI/CD pipelines, it disables parallelization altogether.

These are logical constrains when you consider the weight of running headless browsers locally. But when you’re running against BrowserCat’s fleet, you can safely increase concurrency to a much greater degree. After all, when working with remote browsers, your test workers will often be waiting idle. Why not make the most of your local CPU by filling that time with more tests?

We can increase concurrency in two ways. The first is configure the number of test files run in parallel. A worker will run a particular file’s tests from top to bottom, then load a new file when it finishes.

Let’s make that change:

export default defineConfig({
  // Workers as a percentage of CPUs
  workers: '200%',
  // Workers as a hard-coded number
  workers: 10,
  // Or based on environment
  workers: process.env.CI ? 10 : '200%',
});
[pytest]
# Workers as a hard-coded number
numprocesses = 10

In the above example, we’ve increased the number of test files that will run in parallel. But we can also increase the number of test cases that will run in parallel. I don’t recommend this for most users, as it’s very useful to be able to leverage serial excution.

Nevertheless, the following config will enable parallelization at the test case level:

export default defineConfig({
  // Run all test cases in parallel
  fullyParallel: true,
});
# Not currently supported

Now that you understand how to configure concurrency, it’s time to run some experiments! Only through trial and error will you discover just how many parallel tests each of your testing environments can handle.

As a general rule, I would err a bit on the low side. You want to leave some buffer for competing processes, intermittent issues, and heavy tests you develop in the future.

Nevertheless, we’ve seen dev teams save up to 75 minutes per deploy simply by parallelizing their tests using BrowserCat’s fleet.

Next steps

Now that you’re deployed, I encourage you to explore the app dashboard. It provides realtime data about your usage. And by leveraging different API keys for different functionality, you can even use it to track costs of different features, or different environments.

And if you have any questions, contact us. We’re here to make working with the browser a joy.