Coveros-GitHub-Sandbox/selenified

Draw/Remove Element Border Before & After Screenshot

mshear opened this issue · 3 comments

To aid in test results clarity, we can highlight an element border in color just before a screenshot is taken, and remove it after the screenshot, so that every element validation we perform will have 1 element highlighted on the associated screenshot. This way, if we are validating several elements in succession, we do not end up with multiple highlighted elements in the same screenshot.

This would be helpful because currently only the locator value is provided in the test step, and the screenshot is the whole page.

Seems this should only be applicable to methods within Selenified that validate an element is displayed (not if we're just validating that it's present). Methods such as element.waitForState().displayed(int), or certain app.verify() methods or certain app.azzert() methods.

I'm assuming we don't want this for text validations, because the string itself is already included in the test step (plus, I think that might be a lot more complicated to accomplish). But if there's an easy solution, maybe it actually is useful for text validations and not just elements.

For the elements, I implemented it this way. You probably don't need the actionFlag string variable because you can hard-code the draw & undraw just before & after the screenshot code in Selenified:

My element display validation method, which is used by all my page classes, makes the call to draw, then undraw, as a wrapper around the Selenified method that validates an element is displayed and takes a screenshot:
public void validateElementDisplayed(Element element) {
WebDriver myDriver = app.getDriver();
String myXpath = element.get().xPath();
elementBorderDrawRemove(myDriver, myXpath, "draw");
element.waitForState().displayed(10);
elementBorderDrawRemove(myDriver, myXpath, "remove");
}

I used this code using a string to determine whether we're drawing the border or undrawing it:
public void elementBorderDrawRemove(WebDriver myDriver, String xpath, String actionFlag) {
String borderColor = (actionFlag == "draw") ? "7px solid lime" : "";
WebElement element_node = myDriver.findElement(By.xpath(xpath));
JavascriptExecutor jse = (JavascriptExecutor) myDriver;
jse.executeScript("arguments[0].style.border='"+borderColor+"'", element_node);
}

NOTE: See comment from 5/24 @11:48am EST for updated, more efficient/accurate code sample.

Sorry, seems I might not have the necessary permissions to add a label in order to mark this as a feature request.

Could also simply highlight the element in yellow (background yellow), but I was assuming that folks might like the border better because that way the element's real color is still easy to ascertain when looking at a screenshot so that a development mistake regarding element color can still be identified.

I made it more complicated than it has to be, wasn't reliable. Turns out, for a small minority of elements, the use of element.get().xPath() isn't reliable. Instead, we can just use element.getWebElement() and there use the already accurate/existing locator values from the element definitions we'd already created in our page/functionality classes. Is more reliable this way. No need to do the "find" (By xpath or any other) of the element. Here's the updated code:

public void validateElementDisplayed(Element element) {
	WebDriver myDriver = app.getDriver();	
	WebElement selenifiedElement = element.getWebElement();
	elementBorderDrawRemove(myDriver, selenifiedElement, "draw");
	element.waitForState().displayed(10);
	elementBorderDrawRemove(myDriver, selenifiedElement, "remove");
}

public void elementBorderDrawRemove(WebDriver myDriver, WebElement selenifiedElement, String actionFlag) {
	String borderColor = (actionFlag == "draw") ? "7px solid lime" : "";
	JavascriptExecutor jse = (JavascriptExecutor) myDriver;
    jse.executeScript("arguments[0].style.border='"+borderColor+"'", selenifiedElement);
}