Locate the closest common ancestor of multiple locators in Playwright
import { Locator, Page } from "@playwright/test";
/**
* Get the closest common ancestor among the locators
* @param {Page} page Playwright's page instance
* @param {Locator[]} locators An array of locators to find the closest common ancestor
* @return {Locator} A locator of the closest common ancestor among the given locators
*/
export const getClosestCommonAncestor = (
page: Page,
locators: Locator[]
): Locator => {
let output = page.locator("*");
for (const locator of locators) {
output = output.filter({ has: locator });
}
return output.last();
};
Explanation
1. Find all elements
To get every element on the document, we can use page.locator('*')
. The result locator, when executed, will match every elements on the page. This gives us a universal set of all elements in the page which we can filter later on.
2. Filter for common ancestors
We chain .filter({ has: locator })
for every locators
. For each .filter({ has: locator })
, we get a subset of the universal set of elements that has the specified locator
as a descendant.
Once we iterate through all of the locators
, we are left with a subset of the universal set that are ancestors of all locators
.
3. Get the closest ancestor
From filtering, we have multiple common ancestors ranging from the furthest to closest ones. We can get the closest common ancestor with .last()
.