diff --git a/CHANGELOG.md b/CHANGELOG.md index acb7e67db..32d2552cf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ All notable changes to AET will be documented in this file. - [PR-517](https://github.com/Cognifide/aet/pull/517) Single URL rerun fixed for named URLs ([#487](https://github.com/Cognifide/aet/issues/487)) - [PR-516](https://github.com/Cognifide/aet/pull/516) Added option to change headers added by Chrome instance. ([#515](https://github.com/Cognifide/aet/issues/515)) - [PR-520](https://github.com/Cognifide/aet/pull/520) Fix displaying test tiles +- [PR-518](https://github.com/Cognifide/aet/pull/518) Minimum site height ([#384](https://github.com/Cognifide/aet/issues/384)) ## Version 3.2.2 diff --git a/core/jobs/src/main/java/com/cognifide/aet/job/common/collectors/screen/ScreenCollector.java b/core/jobs/src/main/java/com/cognifide/aet/job/common/collectors/screen/ScreenCollector.java index 3aa9c9f01..6431f8c71 100644 --- a/core/jobs/src/main/java/com/cognifide/aet/job/common/collectors/screen/ScreenCollector.java +++ b/core/jobs/src/main/java/com/cognifide/aet/job/common/collectors/screen/ScreenCollector.java @@ -26,11 +26,28 @@ import com.cognifide.aet.job.common.SeleniumWaitHelper; import com.cognifide.aet.job.common.modifiers.WebElementsLocatorParams; import com.cognifide.aet.vs.ArtifactsDAO; +import org.apache.commons.codec.digest.DigestUtils; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; +import org.openqa.selenium.By; +import org.openqa.selenium.Dimension; +import org.openqa.selenium.NoSuchElementException; +import org.openqa.selenium.OutputType; +import org.openqa.selenium.Point; +import org.openqa.selenium.TakesScreenshot; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebDriverException; +import org.openqa.selenium.WebElement; + + +import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; + import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -41,20 +58,6 @@ import java.util.Map.Entry; import java.util.Set; import java.util.stream.Collectors; -import javax.imageio.ImageIO; -import org.apache.commons.codec.digest.DigestUtils; -import org.apache.commons.collections.CollectionUtils; -import org.apache.commons.io.IOUtils; -import org.apache.commons.lang3.StringUtils; -import org.openqa.selenium.By; -import org.openqa.selenium.Dimension; -import org.openqa.selenium.NoSuchElementException; -import org.openqa.selenium.OutputType; -import org.openqa.selenium.Point; -import org.openqa.selenium.TakesScreenshot; -import org.openqa.selenium.WebDriver; -import org.openqa.selenium.WebDriverException; -import org.openqa.selenium.WebElement; public class ScreenCollector extends WebElementsLocatorParams implements CollectorJob { @@ -212,8 +215,7 @@ private byte[] getImagePart(byte[] fullPage, WebElement webElement) BufferedImage fullImg = ImageIO.read(in); Point point = webElement.getLocation(); Dimension size = webElement.getSize(); - BufferedImage screenshotSection = fullImg.getSubimage(point.getX(), point.getY(), - size.getWidth(), size.getHeight()); + BufferedImage screenshotSection = getSubImage(fullImg, point, size); return bufferedImageToByteArray(screenshotSection); } catch (IOException e) { throw new ProcessingException("Unable to create image from taken screenshot", e); @@ -222,6 +224,18 @@ private byte[] getImagePart(byte[] fullPage, WebElement webElement) } } + BufferedImage getSubImage(BufferedImage fullImg, Point point, Dimension size) { + int width = calculateMeasure(fullImg.getWidth(), size.getWidth(), point.getX()); + int height = calculateMeasure(fullImg.getHeight(), size.getHeight(), point.getY()); + + return fullImg.getSubimage(point.getX(), point.getY(), width, height); + } + + private int calculateMeasure(int fullImgMeasure, int subImgMeasure, int point) { + int result = Math.min(subImgMeasure, fullImgMeasure - point); + return Math.max(result, 1); + } + private byte[] bufferedImageToByteArray(BufferedImage bufferedImage) throws ProcessingException { try (ByteArrayOutputStream temporaryStream = new ByteArrayOutputStream()) { ImageIO.write(bufferedImage, PNG_FORMAT, temporaryStream); diff --git a/core/jobs/src/main/java/com/cognifide/aet/job/common/modifiers/resolution/ResolutionModifier.java b/core/jobs/src/main/java/com/cognifide/aet/job/common/modifiers/resolution/ResolutionModifier.java index 9b64c72b9..ceff87bbe 100644 --- a/core/jobs/src/main/java/com/cognifide/aet/job/common/modifiers/resolution/ResolutionModifier.java +++ b/core/jobs/src/main/java/com/cognifide/aet/job/common/modifiers/resolution/ResolutionModifier.java @@ -23,10 +23,10 @@ import com.cognifide.aet.job.common.utils.javascript.JavaScriptJobExecutor; import com.cognifide.aet.job.common.utils.Sampler; import java.util.Map; +import java.util.function.IntSupplier; import java.util.function.Supplier; import org.apache.commons.lang3.math.NumberUtils; import org.openqa.selenium.Dimension; -import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebDriver.Window; import org.slf4j.Logger; @@ -44,6 +44,7 @@ public class ResolutionModifier implements CollectorJob { private static final int HEIGHT_MAX_SIZE = 35000; private static final int INITIAL_HEIGHT = 300; + private static final int MINIMUM_HEIGHT = 1; private static final int HEIGHT_NOT_DEFINED = 0; private static final int HEIGHT_NOT_CALCULATED = -1; private static final int DEFAULT_SAMPLING_WAIT_PERIOD = 100; @@ -108,6 +109,9 @@ private void setResolution() throws ProcessingException { height = HEIGHT_MAX_SIZE; } else if (height == HEIGHT_NOT_CALCULATED) { throw new ProcessingException("Failed to calculate height, could not parse javascript result to integer"); + } else if (height < MINIMUM_HEIGHT) { + LOG.warn("Detected page height is 0, setting height to 1"); + height = MINIMUM_HEIGHT; } } LOG.info("Setting resolution to {}x{} ", width, height); diff --git a/core/jobs/src/test/java/com/cognifide/aet/job/common/collectors/screen/ScreenCollectorImageTest.java b/core/jobs/src/test/java/com/cognifide/aet/job/common/collectors/screen/ScreenCollectorImageTest.java new file mode 100644 index 000000000..bf6264e96 --- /dev/null +++ b/core/jobs/src/test/java/com/cognifide/aet/job/common/collectors/screen/ScreenCollectorImageTest.java @@ -0,0 +1,101 @@ +/** + * AET + *

+ * Copyright (C) 2013 Cognifide Limited + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ +package com.cognifide.aet.job.common.collectors.screen; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.runners.MockitoJUnitRunner; +import org.openqa.selenium.Dimension; +import org.openqa.selenium.Point; + +import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.io.File; + + +import static org.assertj.core.api.Assertions.assertThat; + +@RunWith(MockitoJUnitRunner.class) +public class ScreenCollectorImageTest { + + private static final Color black = new Color(0); + + @InjectMocks + private ScreenCollector screenCollector; + + private BufferedImage testImage; + + + @Before + public void setup() throws Exception { + String path = getClass().getResource("/screens/48x48.png").getFile(); + File image = new File(path); + testImage = ImageIO.read(image); + } + + @Test + public void testSubImageSize() { + Point point = new org.openqa.selenium.Point(12, 12); + Dimension dimension = new Dimension(24, 24); + + BufferedImage subImage = screenCollector.getSubImage(testImage, point, dimension); + + assertThat(subImage.getHeight()).isEqualTo(24); + assertThat(subImage.getWidth()).isEqualTo(24); + + } + + @Test + public void testSubImageContent() { + Point point = new org.openqa.selenium.Point(12, 12); + Dimension dimension = new Dimension(24, 24); + + BufferedImage subImage = screenCollector.getSubImage(testImage, point, dimension); + boolean onlyBlack = true; + + for (int i = 0; i < subImage.getHeight(); i++) { + for (int j = 0; j < subImage.getWidth(); j++) { + onlyBlack &= black.equals(new Color(subImage.getRGB(i, j))); + } + } + assertThat(onlyBlack).isTrue(); + } + + @Test + public void testSubImageSize_whenElementIsHidden() { + Point point = new Point(0, 0); + Dimension dimension = new Dimension(0, 0); + + BufferedImage subImage = screenCollector.getSubImage(testImage, point, dimension); + + assertThat(subImage.getHeight()).isEqualTo(1); + assertThat(subImage.getWidth()).isEqualTo(1); + } + + @Test + public void testSubImageSize_whenElementIsBiggerThanImage() { + Point point = new Point(20, 20); + Dimension dimension = new Dimension(48, 48); + + BufferedImage subImage = screenCollector.getSubImage(testImage, point, dimension); + + assertThat(subImage.getHeight()).isEqualTo(28); + assertThat(subImage.getWidth()).isEqualTo(28); + } +} diff --git a/core/jobs/src/test/resources/screens/48x48.png b/core/jobs/src/test/resources/screens/48x48.png new file mode 100644 index 000000000..ec742855a Binary files /dev/null and b/core/jobs/src/test/resources/screens/48x48.png differ diff --git a/integration-tests/sample-site/src/main/webapp/sanity/comparators/layout/0px_height_page.jsp b/integration-tests/sample-site/src/main/webapp/sanity/comparators/layout/0px_height_page.jsp new file mode 100644 index 000000000..0c7cf683b --- /dev/null +++ b/integration-tests/sample-site/src/main/webapp/sanity/comparators/layout/0px_height_page.jsp @@ -0,0 +1,28 @@ +<%-- + + AET + + Copyright (C) 2013 Cognifide Limited + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +--%> + + + + +AET Demo Page + + + + diff --git a/integration-tests/sample-site/src/main/webapp/sanity/comparators/layout/0px_height_page_partial.jsp b/integration-tests/sample-site/src/main/webapp/sanity/comparators/layout/0px_height_page_partial.jsp new file mode 100644 index 000000000..d8472ef06 --- /dev/null +++ b/integration-tests/sample-site/src/main/webapp/sanity/comparators/layout/0px_height_page_partial.jsp @@ -0,0 +1,29 @@ +<%-- + + AET + + Copyright (C) 2013 Cognifide Limited + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +--%> + + + + +AET Demo Page + + +

+ + diff --git a/integration-tests/sample-site/src/main/webapp/sanity/comparators/layout/1px_height_page.jsp b/integration-tests/sample-site/src/main/webapp/sanity/comparators/layout/1px_height_page.jsp new file mode 100644 index 000000000..11c5bf002 --- /dev/null +++ b/integration-tests/sample-site/src/main/webapp/sanity/comparators/layout/1px_height_page.jsp @@ -0,0 +1,28 @@ +<%-- + + AET + + Copyright (C) 2013 Cognifide Limited + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +--%> + + + + +AET Demo Page + + + + diff --git a/integration-tests/sample-site/src/main/webapp/sanity/comparators/layout/partial_bigger_than_page.jsp b/integration-tests/sample-site/src/main/webapp/sanity/comparators/layout/partial_bigger_than_page.jsp new file mode 100644 index 000000000..fab881810 --- /dev/null +++ b/integration-tests/sample-site/src/main/webapp/sanity/comparators/layout/partial_bigger_than_page.jsp @@ -0,0 +1,29 @@ +<%-- + + AET + + Copyright (C) 2013 Cognifide Limited + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +--%> + + + + +AET Demo Page + + +
+ + diff --git a/integration-tests/sanity-functional/src/test/java/com/cognifide/aet/sanity/functional/HomePageTilesTest.java b/integration-tests/sanity-functional/src/test/java/com/cognifide/aet/sanity/functional/HomePageTilesTest.java index 7015c751b..ac7b2c690 100644 --- a/integration-tests/sanity-functional/src/test/java/com/cognifide/aet/sanity/functional/HomePageTilesTest.java +++ b/integration-tests/sanity-functional/src/test/java/com/cognifide/aet/sanity/functional/HomePageTilesTest.java @@ -29,9 +29,9 @@ @Modules(GuiceModule.class) public class HomePageTilesTest { - private static final int TESTS = 152; + private static final int TESTS = 156; - private static final int EXPECTED_TESTS_SUCCESS = 88; + private static final int EXPECTED_TESTS_SUCCESS = 92; private static final int EXPECTED_TESTS_CONDITIONALLY_PASSED = 11; diff --git a/integration-tests/sanity-functional/src/test/resources/features/filtering.feature b/integration-tests/sanity-functional/src/test/resources/features/filtering.feature index a3fb34ee2..31b16bb56 100644 --- a/integration-tests/sanity-functional/src/test/resources/features/filtering.feature +++ b/integration-tests/sanity-functional/src/test/resources/features/filtering.feature @@ -37,8 +37,8 @@ Feature: Tests Results Filtering Scenario: Filtering Tests Results: layout Given I have opened sample tests report page When I search for tests containing "layout" - Then There are 39 tiles visible - And Statistics text contains "39 ( 17 / 0 / 22 (11) / 0 )" + Then There are 43 tiles visible + And Statistics text contains "43 ( 17 / 0 / 26 (11) / 0 )" Scenario: Filtering Tests Results: jserrors Given I have opened sample tests report page diff --git a/integration-tests/test-suite/partials/layout.xml b/integration-tests/test-suite/partials/layout.xml index c00480ecd..24cc8b98b 100644 --- a/integration-tests/test-suite/partials/layout.xml +++ b/integration-tests/test-suite/partials/layout.xml @@ -532,5 +532,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +