I'm using Playwright, which lacks an equivalent for JavaScript's closest()
function.
Can I accomplish that using XPath?
I'm using the .NET bindings, but you can convert the following to your environment.
I defined extension methods (input validation excluded for brevity):
public static ILocator Closest(this ILocator locator, string className) =>
locator.Locator($"//ancestor::*[contains(@class, '{className}')]");
public static ILocator Closest(this ILocator locator, string attributeName, string valueName) =>
locator.Locator($"//ancestor::*[contains(@{attributeName}, '{valueName}')]");
public static ILocator Closest(this ILocator locator, string elementName, string attributeName, string valueName) =>
locator.Locator($"//ancestor::{elementName}[contains(@{attributeName}, '{valueName}')]");
Which are used like so:
var closestByClass = myLocator.Closest("foo");
var closestByAttribute = myLocator.Closest("title", "Click this to do foo");
var closestByElementAndAttribute = myLocator.Closest("div", "data-account-balance", "42");
There are some edge cases, but it works for my use case.