What is parallelization?
Parallel testing is also named parallel execution. In parallel testing, we test different modules or applications on multiple browsers in parallel instead of testing them one by one.
Parallelization is different from sequential testing, where we test different modules or functionalities one after another. Even when testing an application on multiple browsers, the tests are executed sequentially on each browser. This testing method is very time-consuming.
Parallel execution helps reduce execution time and effort, thereby reducing delivery time. It proves to be particularly useful in cross-browser testing, compatibility testing, localization, and internalization testing. In situations where we have two versions of the software available and need to check their stability and compatibility, we can run both versions simultaneously and find issues at a faster pace.
Parallelization means running multiple tasks at the same time, which can often significantly improve speed, especially when testing or executing tasks.
Serialization means that tasks are executed one after another in order until all tasks are completed.
Before getting started, it's necessary to have a Browserless service. Browserless can solve complex web crawling and large-scale automation tasks, and it has now achieved fully managed cloud deployment.
Browserless adopts a browser-centric approach, provides powerful headless deployment capabilities, and provides higher performance and reliability. For more information about Browserless, you can click here to learn more.
Why use Puppeteer?
Puppeteer has many maintainers and is very active. It is also built by Chrome developers, so it is one of the highest-quality libraries. So next, we will use Puppeteer to connect Browserless for parallel testing.
Puppeteer-cluster can create multiple puppeteer workers. This library generates a pool of Chromium instances through Puppeteer and helps track operations and errors. It can help us do parallel testing well, but this library does not yet support puppeteer.connect
, so it cannot connect to external browser ports.
So in the following examples, we will use puppeteer-cluster-connect instead:
npm install --save puppeteer
npm install --save puppeteer-cluster-connect
We need to prepare the following function. Just fill in your api key and proxy to start connecting to Browserless:
async function getBrowserWSEndpoint() {
const token = "your api key"; // 'your proxy'
const config = {
proxy: 'your proxy', // required; input format: schema://user:password@host:port eg: http://user:password@localhost:8080
// platform: 'windows', // support: windows, mac, linux
// kernel: 'chromium', // only support: chromium
// kernelMilestone: '128', // support: 128
// args: {
// "--proxy-bypass-list": "detect.nstbrowser.io"
// }, // browser args
// fingerprint: {
// userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.85 Safari/537.36', // userAgent supportted since v0.15.0
// },
};
const query = new URLSearchParams({
token: token, // required
config: JSON.stringify(config),
});
return `https://less.nstbrowser.io/connect?${query.toString()}`;
}
Next, we need to use the connecting method of puppeteer-cluster-connect to connect to Browserless;
Concurrency
is the implementation type of concurrency. Here we set Cluster.CONCURRENCY_CONTEXT
, which means that each URL will create an invisible page (BrowserContext) that does not share data;MaxConcurrency
is the maximum number of concurrencies.RestartFunction
is the method for restarting the port when it crashes.At this point, our Browserless cluster is ready!
import puppeteer from "puppeteer-core";
import { Cluster } from "puppeteer-cluster-connect"
const cluster = await Cluster.connect({
concurrency: Cluster.CONCURRENCY_CONTEXT,
maxConcurrency: 3,
// provide the puppeteer-core library
puppeteer,
puppeteerOptions: {
browserWSEndpoint: await getBrowserWSEndpoint(),
defaultViewport: null
},
// Put restart function callback here
restartFunction: getBrowserWSEndpoint,
});
console.log('cluster is Connected!');
Next, we will conduct a simple parallel test. We hope to quickly access multiple sites in batches in parallel, record the titles of these sites, and take screenshots after the page is loaded to test whether these sites can be accessed normally.
task
method of the cluster obtained in the previous step to create a task. This task contains the operation function corresponding to each browser instance:await cluster.task(async ({ page, data }) => {
const { url, name } = data
// Visit Target Site
await page.goto(url);
console.log(`[${name} page loaded]:`, url);
// Get document title
const documentTitle = await page.evaluate(() => document.title)
console.log(`[${name} title]:`, documentTitle);
// take a screenshot
await page.screenshot({ fullPage: true, path: `${name}.png` });
});
queue
method should be used to add data that needs to be tested in parallel to the clusteridle
and close
methods to close the cluster and all open browser instances:cluster.queue({ url: "https://www.google.com", name: 'google' });
cluster.queue({ url: "https://www.wikipedia.org", name: 'wikipedia' });
cluster.queue({ url: "https://github.com/", name: 'github' });
await cluster.idle();
await cluster.close();
You can view statistics for recent requests and remaining session time in the Browserless menu of the Nstbrowser client.
Do you always need to parallelize your work? Running tests in parallel always requires access to multiple platforms and browsers, which increases our testing costs.
In addition, we may encounter situations where we cannot access all browsers and versions. Browserless can easily help you solve the above problems. It only takes 4 simple steps to easily complete parallel testing.