Managing multiple pages in Playwright test
I was trying to write a test in Playwright that opens a multiplayer game on multiple tabs. This method can be useful for test multi-type applications like chats application etc.
But in my case in my case, I was testing a visual game on a HTML canvas so all I did was a visual regression test using Applitools.
How I approached the problem
- I made an array of Playwright
page
derived from just a singlecontext
. -
From the Playwright pages, I derived an array of Promises which performs the functions configured for each pages so that I can run run the test using:
await Promise.all(tasks)
The way I have my test setup, rather than defining the tests directly, I create modular functions and variables to be able to reuse the functions or variables. This proved useful when working with selectors. For instance:
import { multiplayerMoves, selectors } from "../pages/canva"
// selectors is an object with contains the selectors specific to a page
test("multiplayer", async () => {
test.setTimeout(90000);
const tasks = await multiplayerMoves(2, context, eyes);
await Promise.all(tasks);
});
});
The multiplayerMoves
looked like this
//canva.ts
export const multiplayerMoves = async (
numOfPages: number,
context: BrowserContext,
eyes: Eyes
) => {
// pre-allocating an initialized array with empty null with the page
// the Promise.all is necessary because the async callback in Array.map
// would return a Promise that would resove to what is returned in the callback
const pages = await Promise.all(
Array(numOfPages)
.fill(null)
.map(async () => {
const page = await context.newPage();
return page;
})
);
// mapping through the number of pages and creating a new promise that calls an async IIFE
const tasks = pages.map(async (page, ind) => {
return new Promise((resolve, reject) => {
(async () => {
try {
await page.goto("http://localhost:3000");
// if even, make us of the diagonal movement coordinate on the canva
if (ind % 2 === 0) {
await makeMoves(page, 5, null, "diag");
} else await makeMoves(page, 5, null, "vert");
// making use of the first page in the pages array to take a snapshot and send to applitools
// for visual testing
if (ind === 0) {
await page.waitForTimeout(10000);
await eyes.open(page, "color-board", "multiplayer");
await eyes.check(
"board",
Target.region(selectors.gameboard).layout()
);
await eyes.close();
}
resolve(undefined);
} catch (err) {
reject(err);
}
})();
});
});
// returns an array of promise
return tasks;
};
The makeMoves
function is that interate with the canva rendered on the pages and make moves on the canva depending on the arguments passed to it.
Conclusion
What can you say about this temporary method. I look forward to your comments and learning from you. 🤗