Some testers create XPATH locators that use * instead of the element’s tag:
By locator = By.xpath(“//*[@data-id = ‘See All’]”);
This is a bad practice for a few reasons.
if there are multiple elements on the page that have a data-id attribute with the “See All” value, let’s say one with the span tag and the other with the a tag, the locator using * matches both elements. Specifying the tag in the locator will narrow down the elements that are matched.
since we do not know the element’s tag, we do not know anything about the element. is it visible? is is hidden? is it in the DOM? is it clickable? is it enabled? we cannot make any deductions about the element’s status based on the tag.
The second reason is more serious.
Because, if we find the element with code as follows:
WebElement element = driver.findElement(locator);
everything is ok.
But, as soon as we want to add synchronization so that the code waits for the element before interacting with it, we are going to have to answer a question.
What expected condition should we wait for?
If the element is visible, we can wait for
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30));
wait.until(ExpectedConditions.visibilityOfElementLocated(locator));
WebElement element = driver.findElement(locator);
If the element is enabled (clickable), we can wait for
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30));
wait.until(ExpectedConditions.elementToBeClickable(locator));
WebElement element = driver.findElement(locator);
But we do not know if the element is either visible or enabled.
So, we have to just wait for the element to be present (present in DOM):
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30));
wait.until(ExpectedConditions.presenceOfElementLocated(locator));
WebElement element = driver.findElement(locator);
This is less than ideal as, if the element is actually clickable, the element may be found when it is present but not yet clickable. So clicking on it may generate an exception.
In conclusion, do not use * in a locator.
Replace * with the element tag.
The tag is mandatory in HTML so it is always there.