google-nomulus/javatests/google/registry/webdriver/GoldenImageFinder.java
shicong a7d099d2a3 Enable screenshot comparison in external build
This change actually enabled the screenshot comparison in the
visual regression tests. We used Docker to provision Chrome
and ChromeDriver to eliminate the discrepancy of environment
between local development and Travis CI.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=237811918
2019-03-20 14:25:28 -04:00

118 lines
4.4 KiB
Java

// Copyright 2019 The Nomulus Authors. All Rights Reserved.
//
// 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 google.registry.webdriver;
import static com.google.common.collect.ImmutableSetMultimap.toImmutableSetMultimap;
import static com.google.common.hash.Hashing.sha256;
import static com.google.common.io.MoreFiles.asByteSource;
import com.beust.jcommander.JCommander;
import com.beust.jcommander.Parameter;
import com.beust.jcommander.Parameters;
import com.google.common.collect.Maps;
import com.google.common.io.MoreFiles;
import google.registry.tools.params.ParameterFactory;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Map;
import java.util.stream.Stream;
/** A tool to find the new golden image by selecting the screenshot which appears the most times. */
@Parameters(
separators = " =",
commandDescription = "Find the new golden images from the given screenshots.")
public class GoldenImageFinder {
@Parameter(
names = {"--screenshots_for_goldens_dir"},
description = "Directory to store screenshots generated as candidate of golden images.",
required = true)
private Path screenshotsForGoldensDir;
@Parameter(
names = {"--new_goldens_dir"},
description = "Directory to store the new golden images selected by this application.",
required = true)
private Path newGoldensDir;
@Parameter(
names = {"--existing_goldens_dir"},
description = "Directory to store the existing golden images.",
required = true)
private Path existingGoldensDir;
@Parameter(
names = {"--override_existing_goldens"},
description =
"If set to true, the new golden images are copied to override the existing ones.")
private boolean overrideExistingGoldens = false;
private void run() {
try (Stream<Path> allScreenshots =
Files.find(screenshotsForGoldensDir, 3, (file, attr) -> attr.isRegularFile())) {
if (newGoldensDir.toFile().isDirectory()) {
MoreFiles.deleteRecursively(newGoldensDir);
}
newGoldensDir.toFile().mkdirs();
allScreenshots
.collect(
toImmutableSetMultimap(
imagePath -> imagePath.toFile().getName(), imagePath -> imagePath))
.asMap()
.forEach(
(imageFileName, screenshots) -> {
Map<String, Integer> occurrenceByHash = Maps.newHashMap();
int currNumOccurrence = 0;
Path currImagePath = null;
for (Path screenshot : screenshots) {
String imageHash;
try {
imageHash = asByteSource(screenshot).hash(sha256()).toString();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
int numOccurrence = occurrenceByHash.getOrDefault(imageHash, 0);
occurrenceByHash.put(imageHash, numOccurrence + 1);
if (occurrenceByHash.get(imageHash) > currNumOccurrence) {
currNumOccurrence = occurrenceByHash.get(imageHash);
currImagePath = screenshot;
}
}
try {
Files.copy(currImagePath, newGoldensDir.resolve(imageFileName));
if (overrideExistingGoldens) {
Files.copy(currImagePath, existingGoldensDir.resolve(imageFileName));
}
} catch (IOException e) {
throw new UncheckedIOException(e);
}
});
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
public static void main(String[] args) {
GoldenImageFinder finder = new GoldenImageFinder();
JCommander jCommander = new JCommander(finder);
jCommander.addConverterFactory(new ParameterFactory());
jCommander.parse(args);
finder.run();
}
}