I'm trying to create an extension method which task is to find a button with a specific text. This is what I currently have:
public static IWebElement FindButtonByPartialText(this ISearchContext searchContext, string partialText)
{
partialText = partialText.ToLowerInvariant();
var elements = searchContext.FindElements(By.CssSelector("button, input[type='button']"));
foreach (var e in elements)
{
if (e.TagName == "INPUT")
{
if (e.GetAttribute("value")?.ToLowerInvariant().Contains(partialText) == true)
return e;
}
else if (e.Text.ToLowerInvariant().Contains(partialText))
return e;
}
throw new Exception("foo");
}
(I have set the implicit wait option to 30 seconds)
So, if the page hasn't loaded properly yet, but there is at least one button on the page (with the incorrect text), this will fail miserably I expect, because it doesn't have the proper implicit wait behavior.
What is the correct way to create this extension method so that it waits the proper amount of time before throwing?
CodePudding user response:
You cannot use a CSS selector. You will need to use an xpath expression instead. The | character allows you to search for multiple different kinds of elements. In this case, you can search for buttons or inputs:
private const string FindButtonByPartialTextXPath = "//button[contains(lower-case(.), '{0}')]|//input[@type = 'button' and contains(lower-case(@value), '{0}')]";
public static IWebElement FindButtonByPartialText(this ISearchContext searchContext, string partialText)
{
var xpath = string.Format(FindButtonByPartialTextXPath, parialText.ToLowerInvariant());
var locator = By.XPath(xpath);
return searchContext.FindElement(locator);
}
Note: implicit waits will not guarantee an element is visible or something a user can interact with.
