Skip to content

Commit

Permalink
[visual] Move ignores cut logic into ashot strategy (#2724)
Browse files Browse the repository at this point in the history
  • Loading branch information
uarlouski committed Jun 21, 2022
1 parent 23abec5 commit a48e057
Show file tree
Hide file tree
Showing 80 changed files with 1,788 additions and 1,213 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/gradle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -242,8 +242,8 @@ jobs:
if [[ -n $SAUCELABS_USER && -n $SAUCELABS_KEY ]]; then
declare -a profiles=( ipad )
for profile in "${profiles[@]}"; do
./gradlew :vividus-tests:debugStories -Pvividus.configuration.environments=system/saucelabs \
-Pvividus.configuration.suites=grid \
./gradlew :vividus-tests:debugStories -Pvividus.configuration.environments=system/saucelabs/${profile} \
-Pvividus.configuration.suites=system/${profile} \
-Pvividus.configuration.profiles=saucelabs/web,web/tablet/${profile} \
-Pvividus.selenium.grid.username=${SAUCELABS_USER} \
-Pvividus.selenium.grid.password=${SAUCELABS_KEY}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

package org.vividus.jackson.databind.ui.web;
package org.vividus.jackson.databind.ui;

import java.io.IOException;

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import static ru.yandex.qatools.ashot.shooting.ShootingStrategies.cutting;

import java.util.Map;
import java.util.Optional;
import java.util.function.BiFunction;

import javax.inject.Inject;
Expand All @@ -27,6 +28,7 @@
import org.vividus.selenium.screenshot.strategies.ScreenshotShootingStrategy;
import org.vividus.ui.screenshot.ScreenshotParameters;

import ru.yandex.qatools.ashot.shooting.ElementCroppingDecorator;
import ru.yandex.qatools.ashot.shooting.ShootingStrategies;
import ru.yandex.qatools.ashot.shooting.ShootingStrategy;
import ru.yandex.qatools.ashot.shooting.cutter.CutStrategy;
Expand All @@ -37,6 +39,13 @@ public abstract class AbstractAshotFactory<T extends ScreenshotParameters> imple
private Map<String, ScreenshotShootingStrategy> strategies;
private String screenshotShootingStrategy;

private final ScreenshotCropper screenshotCropper;

protected AbstractAshotFactory(ScreenshotCropper screenshotCropper)
{
this.screenshotCropper = screenshotCropper;
}

protected ShootingStrategy decorateWithFixedCutStrategy(ShootingStrategy original, int headerToCut, int footerToCut)
{
return decorateWithCutStrategy(original, headerToCut, footerToCut, FixedCutStrategy::new);
Expand All @@ -50,6 +59,13 @@ protected ShootingStrategy decorateWithCutStrategy(ShootingStrategy original, in
: original;
}

protected ShootingStrategy decorateWithCropping(ShootingStrategy strategy,
Optional<ScreenshotParameters> screenshotParameters)
{
return new ElementCroppingDecorator(strategy, screenshotCropper,
screenshotParameters.map(ScreenshotParameters::getIgnoreStrategies).orElse(Map.of()));
}

protected ScreenshotShootingStrategy getStrategyBy(String strategyName)
{
ScreenshotShootingStrategy strategy = strategies.get(strategyName);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019-2020 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 @@ -14,7 +14,7 @@
* limitations under the License.
*/

package org.vividus.visual.screenshot;
package org.vividus.selenium.screenshot;

import java.awt.Color;
import java.awt.Graphics2D;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/*
* 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.Point;
import java.awt.image.BufferedImage;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

import org.openqa.selenium.WebDriver;
import org.vividus.selenium.IWebDriverProvider;
import org.vividus.ui.action.ISearchActions;
import org.vividus.ui.action.search.Locator;

import ru.yandex.qatools.ashot.coordinates.Coords;
import ru.yandex.qatools.ashot.coordinates.CoordsProvider;

public class ScreenshotCropper
{
private final ScreenshotDebugger screenshotDebugger;
private final ISearchActions searchActions;
private final CoordsProvider coordsProvider;
private final IWebDriverProvider webDriverProvider;

public ScreenshotCropper(ScreenshotDebugger screenshotDebugger, ISearchActions searchActions,
CoordsProvider coordsProvider, IWebDriverProvider webDriverProvider)
{
this.screenshotDebugger = screenshotDebugger;
this.searchActions = searchActions;
this.coordsProvider = coordsProvider;
this.webDriverProvider = webDriverProvider;
}

public BufferedImage crop(BufferedImage image, Optional<Coords> contextCoords,
Map<IgnoreStrategy, Set<Locator>> ignoreStrategies, int topAdjustment)
{
BufferedImage outputImage = image;
WebDriver webDriver = webDriverProvider.get();

for (IgnoreStrategy strategy : List.of(IgnoreStrategy.ELEMENT, IgnoreStrategy.AREA))
{
Set<Coords> ignore = Optional.ofNullable(ignoreStrategies.get(strategy)).orElse(Set.of()).stream()
.map(searchActions::findElements)
.flatMap(Collection::stream)
.collect(Collectors.collectingAndThen(
Collectors.toList(),
webElementsToIgnore -> coordsProvider.ofElements(webDriver, webElementsToIgnore)
));
if (!ignore.isEmpty())
{
Point adjustment = calculateAdjustment(contextCoords, topAdjustment);
ignore.forEach(c ->
{
c.x += adjustment.x;
c.y += adjustment.y;
});

outputImage = strategy.crop(outputImage, ignore);
screenshotDebugger.debug(this.getClass(), "cropped_by_" + strategy, outputImage);
}
}

return outputImage;
}

protected Point calculateAdjustment(Optional<Coords> contextCoords, int topAdjustment)
{
return new Point(0, -topAdjustment);
}

protected CoordsProvider getCoordsProvider()
{
return coordsProvider;
}

protected IWebDriverProvider getWebDriverProvider()
{
return webDriverProvider;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,31 +16,41 @@

package org.vividus.ui.screenshot;

import java.util.Collection;
import java.util.EnumMap;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.BinaryOperator;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.apache.commons.lang3.Validate;
import org.vividus.selenium.screenshot.IgnoreStrategy;
import org.vividus.ui.action.search.Locator;
import org.vividus.util.property.PropertyMappedCollection;

public abstract class AbstractScreenshotParametersFactory<C extends ScreenshotConfiguration>
implements ScreenshotParametersFactory<C>
public abstract class AbstractScreenshotParametersFactory<C extends ScreenshotConfiguration,
P extends ScreenshotParameters> implements ScreenshotParametersFactory<C>
{
private PropertyMappedCollection<C> screenshotConfigurations;
private String shootingStrategy;
private Map<IgnoreStrategy, Set<Locator>> ignoreStrategies;

protected Optional<C> getDefaultConfiguration()
{
return screenshotConfigurations.getNullable(shootingStrategy);
}

protected Optional<C> getScreenshotConfiguration(Optional<C> screenshotConfiguration, BinaryOperator<C> merger)
{
Optional<C> defaultConfiguration = screenshotConfigurations.getNullable(shootingStrategy);
Optional<C> defaultConfiguration = getDefaultConfiguration();
if (screenshotConfiguration.isEmpty())
{
return defaultConfiguration;
}
else if (defaultConfiguration.isPresent())
{
return Optional.of(merger.apply(screenshotConfiguration.get(), defaultConfiguration.get()));
}
return screenshotConfiguration;
return defaultConfiguration.map(c -> merger.apply(screenshotConfiguration.get(), c))
.or(() -> screenshotConfiguration);
}

protected int ensureValidCutSize(int value, String key)
Expand All @@ -49,15 +59,46 @@ protected int ensureValidCutSize(int value, String key)
return value;
}

protected <R extends ScreenshotParameters> R createWithBaseConfiguration(ScreenshotConfiguration configuration,
Supplier<R> parametersFactory)
protected P createWithBaseConfiguration(ScreenshotConfiguration configuration)
{
R parameters = parametersFactory.get();
Map<IgnoreStrategy, Set<Locator>> stepIgnores = Map.of(
IgnoreStrategy.ELEMENT, configuration.getElementsToIgnore(),
IgnoreStrategy.AREA, configuration.getAreasToIgnore()
);

return createWithBaseConfiguration(configuration, stepIgnores);
}

protected P createWithBaseConfiguration(ScreenshotConfiguration configuration,
Map<IgnoreStrategy, Set<Locator>> stepIgnores)
{
P parameters = createScreenshotParameters();
parameters.setShootingStrategy(configuration.getShootingStrategy());
parameters.setNativeFooterToCut(ensureValidCutSize(configuration.getNativeFooterToCut(), "native footer"));

Map<IgnoreStrategy, Set<Locator>> ignores = new EnumMap<>(IgnoreStrategy.class);

for (Map.Entry<IgnoreStrategy, Set<Locator>> ignoreStrategy : ignoreStrategies.entrySet())
{
IgnoreStrategy cropStrategy = ignoreStrategy.getKey();
Set<Locator> ignore = Stream.concat(
getLocatorsStream(ignoreStrategy.getValue()),
getLocatorsStream(stepIgnores.get(cropStrategy)))
.collect(Collectors.toSet());
ignores.put(cropStrategy, ignore);
}
parameters.setIgnoreStrategies(ignores);

return parameters;
}

protected abstract P createScreenshotParameters();

private Stream<Locator> getLocatorsStream(Set<Locator> locatorsSet)
{
return Optional.ofNullable(locatorsSet).stream().flatMap(Collection::stream);
}

public void setShootingStrategy(String shootingStrategy)
{
this.shootingStrategy = shootingStrategy;
Expand All @@ -67,4 +108,9 @@ public void setScreenshotConfigurations(PropertyMappedCollection<C> screenshotCo
{
this.screenshotConfigurations = screenshotConfigurations;
}

public void setIgnoreStrategies(Map<IgnoreStrategy, Set<Locator>> ignoreStrategies)
{
this.ignoreStrategies = ignoreStrategies;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,16 @@
package org.vividus.ui.screenshot;

import java.util.Optional;
import java.util.Set;

import org.vividus.ui.action.search.Locator;

public class ScreenshotConfiguration
{
private int nativeFooterToCut;
private Optional<String> shootingStrategy = Optional.empty();
private Set<Locator> elementsToIgnore = Set.of();
private Set<Locator> areasToIgnore = Set.of();

public int getNativeFooterToCut()
{
Expand All @@ -42,4 +47,24 @@ public void setShootingStrategy(Optional<String> shootingStrategy)
{
this.shootingStrategy = shootingStrategy;
}

public Set<Locator> getElementsToIgnore()
{
return elementsToIgnore;
}

public void setElementsToIgnore(Set<Locator> elementsToIgnore)
{
this.elementsToIgnore = elementsToIgnore;
}

public Set<Locator> getAreasToIgnore()
{
return areasToIgnore;
}

public void setAreasToIgnore(Set<Locator> areasToIgnore)
{
this.areasToIgnore = areasToIgnore;
}
}
Loading

0 comments on commit a48e057

Please sign in to comment.