Skip to content

Commit 07647eb

Browse files
author
Denys Zaiats
committed
[responsive-validator] - added algorithm for validation that elements are overlapped or not
1 parent 9bdd806 commit 07647eb

File tree

2 files changed

+69
-31
lines changed

2 files changed

+69
-31
lines changed

src/main/java/util/validator/ResponsiveValidator.java

Lines changed: 66 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
package util.validator;
22

33
import org.apache.commons.io.FileUtils;
4+
import org.apache.log4j.Logger;
45
import org.json.simple.JSONArray;
56
import org.json.simple.JSONObject;
7+
import org.openqa.selenium.Dimension;
68
import org.openqa.selenium.*;
9+
import org.openqa.selenium.Point;
710
import util.driver.PageValidator;
811

912
import javax.imageio.ImageIO;
@@ -12,11 +15,16 @@
1215
import java.io.File;
1316
import java.io.IOException;
1417
import java.util.ArrayList;
18+
import java.util.HashMap;
1519
import java.util.List;
20+
import java.util.Map;
1621

1722
public class ResponsiveValidator implements Validator {
1823

24+
private final static Logger LOG = Logger.getLogger(ResponsiveValidator.class);
1925
private static final int MIN_MARGIN = -10000;
26+
private static final String ERROR_KEY = "error";
27+
private static final String REASON_KEY = "reason";
2028
private WebDriver driver;
2129
private String rootElementReadableName;
2230
private WebElement rootElement;
@@ -25,7 +33,8 @@ public class ResponsiveValidator implements Validator {
2533
private WebElement aboveElement;
2634
private WebElement belowElement;
2735
private WebElement containerElement;
28-
private List<WebElement> overlapElements = new ArrayList<>();
36+
private HashMap<WebElement, String> overlapElements = new HashMap<>();
37+
private HashMap<WebElement, String> marginLeftElements = new HashMap<>();
2938
private int minWidth,
3039
maxWidth,
3140
minHeight,
@@ -98,9 +107,15 @@ public ResponsiveValidator inside(WebElement element) {
98107
}
99108

100109
@Override
101-
public ResponsiveValidator notOverlapWith(WebElement element) {
102-
overlapElements.add(element);
103-
throw new UnsupportedCommandException();
110+
public ResponsiveValidator notOverlapWith(WebElement element, String readableName) {
111+
overlapElements.put(element, readableName);
112+
return this;
113+
}
114+
115+
@Override
116+
public ResponsiveValidator sameMarginLeftAs(WebElement element, String readableName) {
117+
marginLeftElements.put(element, readableName);
118+
return this;
104119
}
105120

106121
@Override
@@ -154,7 +169,7 @@ public ResponsiveValidator drawMap() {
154169
@Override
155170
public JSONObject validate() {
156171
JSONObject json = new JSONObject();
157-
json.put("error", false);
172+
json.put(ERROR_KEY, false);
158173

159174
if (rootElement != null) {
160175
JSONArray errorMessage = new JSONArray();
@@ -167,7 +182,8 @@ public JSONObject validate() {
167182
try {
168183
map = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
169184
img = ImageIO.read(map);
170-
} catch (Exception ignored) {
185+
} catch (Exception e) {
186+
LOG.error("Failed to create map file: " + e.getMessage());
171187
}
172188

173189
g = img.createGraphics();
@@ -237,69 +253,80 @@ public JSONObject validate() {
237253
}
238254
if (minWidth > MIN_MARGIN) {
239255
if (widthRoot < minWidth) {
240-
errorMessage.add(String.format("Expected min width of element \"" + rootElementReadableName + "\" is: %spx. Actual width is: %spx", minWidth, widthRoot));
256+
errorMessage.add(String.format("Expected min width of element '%s' is: %spx. Actual width is: %spx", rootElementReadableName, minWidth, widthRoot));
241257
if (drawMap) {
242258
drawElementRect(g, Color.RED, rootElement);
243259
}
244260
}
245261
}
246262
if (maxWidth > MIN_MARGIN) {
247263
if (widthRoot > maxWidth) {
248-
errorMessage.add(String.format("Expected max width of element \"" + rootElementReadableName + "\" is: %spx. Actual width is: %spx", maxWidth, widthRoot));
264+
errorMessage.add(String.format("Expected max width of element '%s' is: %spx. Actual width is: %spx", rootElementReadableName, maxWidth, widthRoot));
249265
if (drawMap) {
250266
drawElementRect(g, Color.RED, rootElement);
251267
}
252268
}
253269
}
254270
if (minHeight > MIN_MARGIN) {
255271
if (heightRoot < minHeight) {
256-
errorMessage.add(String.format("Expected min height of element \"" + rootElementReadableName + "\" is: %spx. Actual height is: %spx", minHeight, heightRoot));
272+
errorMessage.add(String.format("Expected min height of element '%s' is: %spx. Actual height is: %spx", rootElementReadableName, minHeight, heightRoot));
257273
if (drawMap) {
258274
drawElementRect(g, Color.RED, rootElement);
259275
}
260276
}
261277
}
262278
if (maxHeight > MIN_MARGIN) {
263279
if (heightRoot > maxHeight) {
264-
errorMessage.add(String.format("Expected max height of element \"" + rootElementReadableName + "\" is: %spx. Actual height is: %spx", maxHeight, heightRoot));
280+
errorMessage.add(String.format("Expected max height of element '%s' is: %spx. Actual height is: %spx", rootElementReadableName, maxHeight, heightRoot));
265281
if (drawMap) {
266282
drawElementRect(g, Color.RED, rootElement);
267283
}
268284
}
269285
}
270286
if (minTopMargin > MIN_MARGIN && minRightMargin > MIN_MARGIN && minBottomMargin > MIN_MARGIN && minLeftMargin > MIN_MARGIN) {
271287

272-
if (xRoot < minLeftMargin){
273-
errorMessage.add(String.format("Expected min left margin of element \"" + rootElementReadableName + "\" is: %spx. Actual left margin is: %spx", minLeftMargin, xRoot));
288+
if (xRoot < minLeftMargin) {
289+
errorMessage.add(String.format("Expected min left margin of element '%s' is: %spx. Actual left margin is: %spx", rootElementReadableName, minLeftMargin, xRoot));
274290
}
275-
if (yRoot < minTopMargin){
276-
errorMessage.add(String.format("Expected min top margin of element \"" + rootElementReadableName + "\" is: %spx. Actual top margin is: %spx", minTopMargin, yRoot));
291+
if (yRoot < minTopMargin) {
292+
errorMessage.add(String.format("Expected min top margin of element '%s' is: %spx. Actual top margin is: %spx", rootElementReadableName, minTopMargin, yRoot));
277293
}
278-
if (elementRightMargin < minRightMargin){
279-
errorMessage.add(String.format("Expected min top margin of element \"" + rootElementReadableName + "\" is: %spx. Actual right margin is: %spx", minRightMargin, elementRightMargin));
294+
if (elementRightMargin < minRightMargin) {
295+
errorMessage.add(String.format("Expected min top margin of element '%s' is: %spx. Actual right margin is: %spx", rootElementReadableName, minRightMargin, elementRightMargin));
280296
}
281-
if (elementBottomMargin < minBottomMargin){
282-
errorMessage.add(String.format("Expected min bottom margin of element \"" + rootElementReadableName + "\" is: %spx. Actual bottom margin is: %spx", minBottomMargin, elementBottomMargin));
297+
if (elementBottomMargin < minBottomMargin) {
298+
errorMessage.add(String.format("Expected min bottom margin of element '%s' is: %spx. Actual bottom margin is: %spx", rootElementReadableName, minBottomMargin, elementBottomMargin));
283299
}
284300
}
285301
if (maxTopMargin > MIN_MARGIN && maxRightMargin > MIN_MARGIN && maxBottomMargin > MIN_MARGIN && maxLeftMargin > MIN_MARGIN) {
286-
if (xRoot > maxLeftMargin){
287-
errorMessage.add(String.format("Expected max left margin of element \"" + rootElementReadableName + "\" is: %spx. Actual left margin is: %spx", maxLeftMargin, xRoot));
302+
if (xRoot > maxLeftMargin) {
303+
errorMessage.add(String.format("Expected max left margin of element '%s' is: %spx. Actual left margin is: %spx", rootElementReadableName, maxLeftMargin, xRoot));
288304
}
289-
if (yRoot > maxTopMargin){
290-
errorMessage.add(String.format("Expected max top margin of element \"" + rootElementReadableName + "\" is: %spx. Actual top margin is: %spx", maxTopMargin, yRoot));
305+
if (yRoot > maxTopMargin) {
306+
errorMessage.add(String.format("Expected max top margin of element '%s' is: %spx. Actual top margin is: %spx", rootElementReadableName, maxTopMargin, yRoot));
291307
}
292-
if (elementRightMargin > maxRightMargin){
293-
errorMessage.add(String.format("Expected max right margin of element \"" + rootElementReadableName + "\" is: %spx. Actual right margin is: %spx", maxRightMargin, elementRightMargin));
308+
if (elementRightMargin > maxRightMargin) {
309+
errorMessage.add(String.format("Expected max right margin of element '%s' is: %spx. Actual right margin is: %spx", rootElementReadableName, maxRightMargin, elementRightMargin));
294310
}
295-
if (elementBottomMargin > maxBottomMargin){
296-
errorMessage.add(String.format("Expected max bottom margin of element \"" + rootElementReadableName + "\" is: %spx. Actual bottom margin is: %spx", maxBottomMargin, elementBottomMargin));
311+
if (elementBottomMargin > maxBottomMargin) {
312+
errorMessage.add(String.format("Expected max bottom margin of element '%s' is: %spx. Actual bottom margin is: %spx", rootElementReadableName, maxBottomMargin, elementBottomMargin));
313+
}
314+
}
315+
if (!overlapElements.isEmpty()) {
316+
for (Map.Entry<WebElement, String> entry : overlapElements.entrySet()) {
317+
if (elementsAreOverlapped(rootElement, entry.getKey())) {
318+
errorMessage.add(String.format("Element '%s' is overlapped with element '%s' but should not", rootElementReadableName, entry.getValue()));
319+
if (drawMap) {
320+
drawElementRect(g, Color.RED, rootElement);
321+
drawElementRect(g, Color.MAGENTA, entry.getKey());
322+
}
323+
}
297324
}
298325
}
299326

300327
if (!errorMessage.isEmpty()) {
301-
json.put("error", true);
302-
json.put("reason", errorMessage);
328+
json.put(ERROR_KEY, true);
329+
json.put(REASON_KEY, errorMessage);
303330
}
304331

305332
if (drawMap) {
@@ -315,13 +342,22 @@ public JSONObject validate() {
315342
}
316343
}
317344
} else {
318-
json.put("error", true);
319-
json.put("reason", "Set root web element");
345+
json.put(ERROR_KEY, true);
346+
json.put(REASON_KEY, "Set root web element");
320347
}
321348

322349
return json;
323350
}
324351

352+
private boolean elementsAreOverlapped(WebElement rootElement, WebElement elementOverlapWith) {
353+
Point elLoc = elementOverlapWith.getLocation();
354+
Dimension elSize = elementOverlapWith.getSize();
355+
return (xRoot > elLoc.x && yRoot > elLoc.y && xRoot < elLoc.x + elSize.width && yRoot < elLoc.y + elSize.height)
356+
|| (xRoot + widthRoot > elLoc.x && yRoot > elLoc.y && xRoot + widthRoot < elLoc.x + elSize.width && yRoot < elLoc.y + elSize.height)
357+
|| (xRoot > elLoc.x && yRoot + heightRoot > elLoc.y && xRoot < elLoc.x + elSize.width && yRoot + heightRoot < elLoc.y + elSize.height)
358+
|| (xRoot + widthRoot > elLoc.x && yRoot + heightRoot > elLoc.y && xRoot + widthRoot < elLoc.x + elSize.width && yRoot + widthRoot < elLoc.y + elSize.height);
359+
}
360+
325361
private void drawElementRect(Graphics g, Color color, WebElement element) {
326362
g.setColor(color);
327363
g.drawRect(element.getLocation().x, element.getLocation().y, element.getSize().width, element.getSize().height);

src/main/java/util/validator/Validator.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ interface Validator {
1616

1717
ResponsiveValidator inside(WebElement element);
1818

19-
ResponsiveValidator notOverlapWith(WebElement element);
19+
ResponsiveValidator notOverlapWith(WebElement element, String readableName);
20+
21+
ResponsiveValidator sameMarginLeftAs(WebElement element, String readableName);
2022

2123
ResponsiveValidator minWidth(int width);
2224

0 commit comments

Comments
 (0)