Skip to content

Commit

Permalink
[plugin-mobile-app] Add full view shooting strategy
Browse files Browse the repository at this point in the history
  • Loading branch information
uarlouski committed Mar 22, 2022
1 parent 79c5657 commit 923e796
Show file tree
Hide file tree
Showing 53 changed files with 977 additions and 170 deletions.
1 change: 1 addition & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
[submodule "vividus-build-system"]
path = vividus-build-system
url = https://github.com/vividus-framework/vividus-build-system.git
branch = full-page-screenshot
21 changes: 21 additions & 0 deletions docs/modules/plugins/pages/plugin-visual.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,27 @@ When I <action> baseline with `scrollable-element-context` using screenshot conf
|51 |SIMPLE |
----

==== Strategies

[cols="1,3", options="header"]
|===

|Name
|Description

|`SIMPLE`
|Used to take a screenshot of current viewport.

|`FULL`
|Used to take a screenshot of whole application view. The strategy starts shooting at the top position
of the application view and ends at the bottom position, once the shooting is done the initial top position
gets restored.

For iOS platforrm make sure to set the `screenshotQuality` property to `0` to ensure screenshot pixels
consistensy, please see https://github.com/appium/appium-xcuitest-driver[XCUI capabililties] for more details.

|===

== Steps

=== Run simple visual test
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019-2021 the original author or authors.
* Copyright 2019-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -16,20 +16,13 @@

package org.vividus.selenium.screenshot;

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Optional;

import javax.imageio.ImageIO;

import org.apache.commons.io.FileUtils;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.SearchContext;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.slf4j.Logger;
Expand Down Expand Up @@ -58,15 +51,6 @@ protected AbstractScreenshotTaker(IWebDriverProvider webDriverProvider,
this.screenshotDebugger = screenshotDebugger;
}

@Override
public BufferedImage takeViewportScreenshot() throws IOException
{
try (InputStream inputStream = new ByteArrayInputStream(takeScreenshotAsByteArray()))
{
return ImageIO.read(inputStream);
}
}

@Override
public Path takeScreenshot(Path screenshotFilePath) throws IOException
{
Expand Down Expand Up @@ -116,7 +100,7 @@ protected String generateScreenshotFileName(String screenshotName)

protected byte[] takeScreenshotAsByteArray()
{
return webDriverProvider.getUnwrapped(TakesScreenshot.class).getScreenshotAs(OutputType.BYTES);
return ScreenshotUtils.takeScreenshotAsByteArray(getWebDriverProvider().get());
}

protected IWebDriverProvider getWebDriverProvider()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019-2021 the original author or authors.
* Copyright 2019-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -16,7 +16,6 @@

package org.vividus.selenium.screenshot;

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Optional;
Expand All @@ -25,7 +24,5 @@ public interface ScreenshotTaker
{
Optional<Screenshot> takeScreenshot(String screenshotName);

BufferedImage takeViewportScreenshot() throws IOException;

Path takeScreenshot(Path screenshotFilePath) throws IOException;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright 2019-2022 the original author or authors.
*
* 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
*
* https://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 org.vividus.selenium.screenshot;

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.imageio.ImageIO;

import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.vividus.selenium.WebDriverUtil;

public final class ScreenshotUtils
{
private ScreenshotUtils()
{
}

public static BufferedImage takeViewportScreenshot(WebDriver webDriver) throws IOException
{
try (InputStream inputStream = new ByteArrayInputStream(takeScreenshotAsByteArray(webDriver)))
{
return ImageIO.read(inputStream);
}
}

public static byte[] takeScreenshotAsByteArray(WebDriver webDriver)
{
return WebDriverUtil.unwrap(webDriver, TakesScreenshot.class).getScreenshotAs(OutputType.BYTES);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019-2021 the original author or authors.
* Copyright 2019-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -27,7 +27,8 @@
import org.vividus.context.VariableContext;
import org.vividus.reporter.event.AttachmentPublishEvent;
import org.vividus.reporter.model.Attachment;
import org.vividus.selenium.screenshot.ScreenshotTaker;
import org.vividus.selenium.IWebDriverProvider;
import org.vividus.selenium.screenshot.ScreenshotUtils;
import org.vividus.softassert.ISoftAssert;
import org.vividus.ui.action.BarcodeActions;
import org.vividus.variable.VariableScope;
Expand All @@ -36,16 +37,16 @@

public class BarcodeSteps
{
private final ScreenshotTaker screenshotTaker;
private final IWebDriverProvider webDriverProvider;
private final BarcodeActions barcodeActions;
private final VariableContext variableContext;
private final ISoftAssert softAssert;
private final EventBus eventBus;

public BarcodeSteps(ScreenshotTaker screenshotTaker, BarcodeActions barcodeActions,
public BarcodeSteps(IWebDriverProvider webDriverProvider, BarcodeActions barcodeActions,
VariableContext variableContext, ISoftAssert softAssert, EventBus eventBus)
{
this.screenshotTaker = screenshotTaker;
this.webDriverProvider = webDriverProvider;
this.barcodeActions = barcodeActions;
this.variableContext = variableContext;
this.softAssert = softAssert;
Expand Down Expand Up @@ -74,7 +75,7 @@ public BarcodeSteps(ScreenshotTaker screenshotTaker, BarcodeActions barcodeActio
@When("I scan barcode from screen and save result to $scopes variable `$variableName`")
public void scanBarcode(Set<VariableScope> scopes, String variableName) throws IOException
{
BufferedImage viewportScreenshot = screenshotTaker.takeViewportScreenshot();
BufferedImage viewportScreenshot = ScreenshotUtils.takeViewportScreenshot(webDriverProvider.get());
try
{
String result = barcodeActions.scanBarcode(viewportScreenshot);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019-2021 the original author or authors.
* Copyright 2019-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -17,19 +17,31 @@
package org.vividus.ui.util;

import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

public final class ImageUtils
{
private static final String PNG_EXT = "png";

private ImageUtils()
{
}

public static void writeAsPng(BufferedImage toWrite, File location) throws IOException
public static void writeAsPng(BufferedImage image, File location) throws IOException
{
ImageIO.write(image, PNG_EXT, new File(location.getAbsolutePath() + '.' + PNG_EXT));
}

public static byte[] encodeAsPng(BufferedImage image) throws IOException
{
ImageIO.write(toWrite, "png", new File(location.getAbsolutePath() + ".png"));
try (ByteArrayOutputStream output = new ByteArrayOutputStream())
{
ImageIO.write(image, PNG_EXT, output);
return output.toByteArray();
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019-2021 the original author or authors.
* Copyright 2019-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -21,17 +21,16 @@
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.withSettings;

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
Expand All @@ -48,14 +47,13 @@
import org.junit.jupiter.api.io.TempDir;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockedStatic;
import org.mockito.junit.jupiter.MockitoExtension;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.SearchContext;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.vividus.selenium.IWebDriverProvider;
import org.vividus.util.ResourceUtils;

import ru.yandex.qatools.ashot.AShot;

Expand All @@ -81,25 +79,6 @@ void afterEach()
verifyNoMoreInteractions(webDriverProvider, takesScreenshot);
}

private void mockScreenshotTaking()
{
byte[] bytes = ResourceUtils.loadResourceAsByteArray(getClass(), IMAGE_PNG);

when(webDriverProvider.getUnwrapped(TakesScreenshot.class)).thenReturn(takesScreenshot);
when(takesScreenshot.getScreenshotAs(OutputType.BYTES)).thenReturn(bytes);
}

@Test
void shouldTakeViewportScreenshot() throws IOException
{
mockScreenshotTaking();

BufferedImage image = testScreenshotTaker.takeViewportScreenshot();

assertEquals(400, image.getWidth());
assertEquals(600, image.getHeight());
}

@Test
void shouldGenerateScreenshotFileName()
{
Expand All @@ -111,20 +90,38 @@ void shouldGenerateScreenshotFileName()
@Test
void shouldNotPublishEmptyScreenshotData(@TempDir Path path) throws IOException
{
testScreenshotTaker.screenshot = new byte[0];
assertNull(testScreenshotTaker.takeScreenshot(path.resolve(IMAGE_PNG)));
assertThat(testLogger.getLoggingEvents(), empty());
try (MockedStatic<ScreenshotUtils> utils = mockStatic(ScreenshotUtils.class))
{
testScreenshotTaker.screenshot = new byte[0];

WebDriver webDriver = mock(WebDriver.class);
when(webDriverProvider.get()).thenReturn(webDriver);
utils.when(() -> ScreenshotUtils.takeScreenshotAsByteArray(webDriver))
.thenReturn(testScreenshotTaker.screenshot);

assertNull(testScreenshotTaker.takeScreenshot(path.resolve(IMAGE_PNG)));
assertThat(testLogger.getLoggingEvents(), empty());
}
}

@Test
void shouldPublishScreenshot(@TempDir Path path) throws IOException
{
testScreenshotTaker.screenshot = new byte[1];
Path screenshotPath = testScreenshotTaker.takeScreenshot(path.resolve(IMAGE_PNG));
assertTrue(Files.exists(screenshotPath));
assertArrayEquals(testScreenshotTaker.screenshot, Files.readAllBytes(screenshotPath));
assertThat(testLogger.getLoggingEvents(), equalTo(List.of(
info("Screenshot was taken: {}", screenshotPath.toAbsolutePath()))));
try (MockedStatic<ScreenshotUtils> utils = mockStatic(ScreenshotUtils.class))
{
testScreenshotTaker.screenshot = new byte[1];

WebDriver webDriver = mock(WebDriver.class);
when(webDriverProvider.get()).thenReturn(webDriver);
utils.when(() -> ScreenshotUtils.takeScreenshotAsByteArray(webDriver))
.thenReturn(testScreenshotTaker.screenshot);

Path screenshotPath = testScreenshotTaker.takeScreenshot(path.resolve(IMAGE_PNG));
assertTrue(Files.exists(screenshotPath));
assertArrayEquals(testScreenshotTaker.screenshot, Files.readAllBytes(screenshotPath));
assertThat(testLogger.getLoggingEvents(), equalTo(List.of(
info("Screenshot was taken: {}", screenshotPath.toAbsolutePath()))));
}
}

@Test
Expand Down Expand Up @@ -177,11 +174,5 @@ public Optional<Screenshot> takeScreenshot(String screenshotName)
{
throw new UnsupportedOperationException();
}

@Override
protected byte[] takeScreenshotAsByteArray()
{
return screenshot == null ? super.takeScreenshotAsByteArray() : screenshot;
}
}
}
Loading

0 comments on commit 923e796

Please sign in to comment.