Add screenshot tests for the new registrar console (#2577)
This required updating to a newer version of Selenium, building the console dist/ folder, and serving that folder.
@@ -910,6 +910,9 @@ task fragileTest(type: FilteringTest) {
|
||||
// Common exclude pattern. See README in parent directory for explanation.
|
||||
tests = fragileTestPatterns
|
||||
|
||||
// Screenshot tests depend on the console being built
|
||||
dependsOn(rootProject.project('console-webapp').tasks.named('buildConsoleWebapp'))
|
||||
|
||||
if (rootProject.findProperty("skipDockerIncompatibleTests") == "true") {
|
||||
exclude dockerIncompatibleTestPatterns
|
||||
}
|
||||
|
||||
@@ -256,6 +256,7 @@ commons-collections:commons-collections:3.2.2=checkstyle
|
||||
commons-dbutils:commons-dbutils:1.8.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
commons-io:commons-io:2.17.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
commons-logging:commons-logging:1.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
dev.failsafe:failsafe:3.3.2=testCompileClasspath,testRuntimeClasspath
|
||||
dnsjava:dnsjava:3.6.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
guru.nidi.com.eclipsesource.j2v8:j2v8_linux_x86_64:4.6.0=testRuntimeClasspath
|
||||
guru.nidi.com.eclipsesource.j2v8:j2v8_macosx_x86_64:4.6.0=testRuntimeClasspath
|
||||
@@ -326,9 +327,11 @@ io.opentelemetry:opentelemetry-api:1.42.1=testCompileClasspath,testRuntimeClassp
|
||||
io.opentelemetry:opentelemetry-bom:1.33.0=testRuntimeClasspath
|
||||
io.opentelemetry:opentelemetry-context:1.37.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath
|
||||
io.opentelemetry:opentelemetry-context:1.42.1=testCompileClasspath,testRuntimeClasspath
|
||||
io.opentelemetry:opentelemetry-exporter-logging:1.42.1=testCompileClasspath,testRuntimeClasspath
|
||||
io.opentelemetry:opentelemetry-sdk-common:1.37.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath
|
||||
io.opentelemetry:opentelemetry-sdk-common:1.42.1=testCompileClasspath,testRuntimeClasspath
|
||||
io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi:1.42.1=testCompileClasspath,testRuntimeClasspath
|
||||
io.opentelemetry:opentelemetry-sdk-extension-autoconfigure:1.42.1=testCompileClasspath,testRuntimeClasspath
|
||||
io.opentelemetry:opentelemetry-sdk-logs:1.37.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath
|
||||
io.opentelemetry:opentelemetry-sdk-logs:1.42.1=testCompileClasspath,testRuntimeClasspath
|
||||
io.opentelemetry:opentelemetry-sdk-metrics:1.37.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath
|
||||
@@ -400,7 +403,7 @@ org.apache.beam:beam-vendor-grpc-1_60_1:0.2=compileClasspath,deploy_jar,nonprodC
|
||||
org.apache.beam:beam-vendor-guava-32_1_2-jre:0.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.commons:commons-compress:1.26.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.commons:commons-csv:1.12.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.commons:commons-exec:1.3=testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.commons:commons-exec:1.4.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.commons:commons-lang3:3.14.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.commons:commons-text:1.12.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.ftpserver:ftplet-api:1.2.0=testCompileClasspath,testRuntimeClasspath
|
||||
@@ -493,7 +496,8 @@ org.joda:joda-money:2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,no
|
||||
org.json:json:20160212=soy
|
||||
org.json:json:20240303=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.jsoup:jsoup:1.18.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.jspecify:jspecify:0.3.0=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.jspecify:jspecify:0.3.0=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath
|
||||
org.jspecify:jspecify:1.0.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.junit-pioneer:junit-pioneer:2.3.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.junit.jupiter:junit-jupiter-api:5.11.2=testCompileClasspath,testRuntimeClasspath
|
||||
org.junit.jupiter:junit-jupiter-engine:5.11.2=testCompileClasspath,testRuntimeClasspath
|
||||
@@ -530,16 +534,24 @@ org.pcollections:pcollections:3.1.4=annotationProcessor,errorprone,nonprodAnnota
|
||||
org.postgresql:postgresql:42.7.3=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.reflections:reflections:0.10.2=checkstyle
|
||||
org.rnorth.duct-tape:duct-tape:1.0.8=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-api:3.141.59=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-chrome-driver:3.141.59=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-edge-driver:3.141.59=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-firefox-driver:3.141.59=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-ie-driver:3.141.59=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-java:3.141.59=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-opera-driver:3.141.59=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-remote-driver:3.141.59=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-safari-driver:3.141.59=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-support:3.141.59=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-api:4.25.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-chrome-driver:4.25.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-chromium-driver:4.25.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-devtools-v127:4.25.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-devtools-v128:4.25.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-devtools-v129:4.25.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-devtools-v85:4.25.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-edge-driver:4.25.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-firefox-driver:4.25.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-http:4.25.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-ie-driver:4.25.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-java:4.25.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-json:4.25.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-manager:4.25.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-os:4.25.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-remote-driver:4.25.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-safari-driver:4.25.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-support:4.25.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.slf4j:jcl-over-slf4j:1.7.36=testCompileClasspath,testRuntimeClasspath
|
||||
org.slf4j:jul-to-slf4j:1.7.30=testRuntimeClasspath
|
||||
org.slf4j:slf4j-api:2.0.16=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
|
||||
@@ -34,17 +34,20 @@ public final class RegistryTestServer {
|
||||
|
||||
public static final ImmutableMap<String, Path> RUNFILES =
|
||||
new ImmutableMap.Builder<String, Path>()
|
||||
.put("/index.html",
|
||||
.put(
|
||||
"/index.html",
|
||||
PROJECT_ROOT.resolve("core/src/main/java/google/registry/ui/html/index.html"))
|
||||
.put("/error.html",
|
||||
.put(
|
||||
"/error.html",
|
||||
PROJECT_ROOT.resolve("core/src/main/java/google/registry/ui/html/error.html"))
|
||||
.put("/assets/js/*", RESOURCES_DIR.resolve("google/registry/ui"))
|
||||
.put("/assets/css/*", RESOURCES_DIR.resolve("google/registry/ui/css"))
|
||||
.put("/assets/sources/*", PROJECT_ROOT)
|
||||
.put("/assets/*", PROJECT_ROOT.resolve("core/src/main/java/google/registry/ui/assets"))
|
||||
.put("/console/*", PROJECT_ROOT.resolve("console-webapp/staged/dist"))
|
||||
.build();
|
||||
|
||||
private static final ImmutableList<Route> ROUTES =
|
||||
public static final ImmutableList<Route> ROUTES =
|
||||
ImmutableList.of(
|
||||
// Frontend Services
|
||||
route("/whois/*", FrontendServlet.class),
|
||||
|
||||
@@ -0,0 +1,162 @@
|
||||
// Copyright 2024 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.truth.Truth.assertThat;
|
||||
import static google.registry.server.Fixture.BASIC;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import google.registry.model.console.GlobalRole;
|
||||
import google.registry.model.console.RegistrarRole;
|
||||
import google.registry.server.RegistryTestServer;
|
||||
import java.util.List;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
import org.junitpioneer.jupiter.RetryingTest;
|
||||
import org.openqa.selenium.By;
|
||||
import org.openqa.selenium.WebElement;
|
||||
|
||||
/**
|
||||
* Tests for the 2024 registrar console, served from the Angular staged distribution.
|
||||
*
|
||||
* <p>When running the tests locally, be sure to build the console webapp first (the
|
||||
* "buildConsoleWebapp" Gradle command, or the "npm run build" command) otherwise the tests will
|
||||
* fail.
|
||||
*
|
||||
* <p>In general, for tests, we load the home page then click on elements to transfer pages. This is
|
||||
* because we aren't really serving the webapp the same way that an actual webserver (e.g. Express)
|
||||
* would, we're just statically serving the distribution. As a result, we cannot load URLs, e.g.
|
||||
* "/#/settings", directly. Put another way, because we don't have a service actually serving the
|
||||
* console, we have to access /console/index.html directly to load the raw file itself, rather than
|
||||
* accessing /console.
|
||||
*
|
||||
* <p>NB: the calls to Thread.sleep are unfortunate but seem to be necessary. Often when we click on
|
||||
* something, that element is highlighted for a very small amount of time after we click it, with
|
||||
* the color fading over a short period of time. We must wait for the highlighting to fade to get
|
||||
* cnosistent images to avoid spurious failures.
|
||||
*/
|
||||
public class ConsoleScreenshotTest extends WebDriverTestCase {
|
||||
|
||||
@RegisterExtension
|
||||
final TestServerExtension server =
|
||||
new TestServerExtension.Builder()
|
||||
.setRunfiles(RegistryTestServer.RUNFILES)
|
||||
.setRoutes(RegistryTestServer.ROUTES)
|
||||
.setFixtures(BASIC)
|
||||
.setEmail("Marla.Singer@crr.com") // from makeRegistrarContact3
|
||||
.setRegistryLockEmail("Marla.Singer.RegistryLock@crr.com")
|
||||
.build();
|
||||
|
||||
@BeforeEach
|
||||
void beforeEach() throws Exception {
|
||||
server.setRegistrarRoles(ImmutableMap.of("TheRegistrar", RegistrarRole.ACCOUNT_MANAGER));
|
||||
loadHomePage();
|
||||
}
|
||||
|
||||
@RetryingTest(3)
|
||||
void index() throws Exception {
|
||||
driver.diffPage("page");
|
||||
}
|
||||
|
||||
@RetryingTest(3)
|
||||
void index_registrarSelectDropdown() throws Exception {
|
||||
selectRegistrar();
|
||||
driver.diffPage("selectedRegistrar");
|
||||
assertThat(driver.getCurrentUrl()).endsWith("?registrarId=TheRegistrar");
|
||||
}
|
||||
|
||||
@RetryingTest(3)
|
||||
void dums_mainPage() throws Exception {
|
||||
clickSidebarElementByName("Domains");
|
||||
driver.diffPage("noRegistrarSelected");
|
||||
selectRegistrar();
|
||||
driver.waitForElementToNotExist(By.tagName("mat-spinner"));
|
||||
Thread.sleep(50);
|
||||
driver.diffPage("registrarSelected");
|
||||
driver.findElement(By.cssSelector("mat-table button")).click();
|
||||
Thread.sleep(100);
|
||||
driver.diffPage("actionsButtonClicked");
|
||||
}
|
||||
|
||||
@RetryingTest(3)
|
||||
void settingsPage() throws Exception {
|
||||
clickSidebarElementByName("Settings");
|
||||
driver.diffPage("noRegistrarSelected");
|
||||
selectRegistrar();
|
||||
driver.diffPage("registrarSelected_contacts");
|
||||
driver.findElement(By.cssSelector("a[routerLink=\"whois\"]")).click();
|
||||
Thread.sleep(500);
|
||||
driver.diffPage("registrarSelected_whois");
|
||||
driver.findElement(By.cssSelector("a[routerLink=\"security\"]")).click();
|
||||
Thread.sleep(500);
|
||||
driver.diffPage("registrarSelected_security");
|
||||
}
|
||||
|
||||
@RetryingTest(3)
|
||||
void billingInfo() throws Exception {
|
||||
clickSidebarElementByName("Billing Info");
|
||||
driver.diffPage("noRegistrarSelected");
|
||||
selectRegistrar();
|
||||
driver.diffPage("registrarSelected");
|
||||
}
|
||||
|
||||
@RetryingTest(3)
|
||||
void resources() throws Exception {
|
||||
clickSidebarElementByName("Resources");
|
||||
driver.diffPage("page");
|
||||
}
|
||||
|
||||
@RetryingTest(3)
|
||||
void support() throws Exception {
|
||||
clickSidebarElementByName("Support");
|
||||
driver.diffPage("page");
|
||||
}
|
||||
|
||||
@RetryingTest(3)
|
||||
void globalRole_registrars() throws Exception {
|
||||
server.setGlobalRole(GlobalRole.SUPPORT_LEAD);
|
||||
loadHomePage();
|
||||
driver.diffPage("homePage");
|
||||
clickSidebarElementByName("Registrars");
|
||||
driver.diffPage("registrarsPage");
|
||||
}
|
||||
|
||||
private void clickSidebarElementByName(String name) throws Exception {
|
||||
WebElement appContainer =
|
||||
driver.findElement(By.cssSelector("mat-sidenav-container.console-app__container"));
|
||||
List<WebElement> sidebarElems =
|
||||
appContainer.findElements(By.cssSelector("mat-tree-node,mat-nested-tree-node"));
|
||||
for (WebElement elem : sidebarElems) {
|
||||
if (elem.getText().contains(name)) {
|
||||
elem.click();
|
||||
break;
|
||||
}
|
||||
}
|
||||
Thread.sleep(100);
|
||||
}
|
||||
|
||||
private void loadHomePage() throws InterruptedException {
|
||||
driver.get(server.getUrl("/console/index.html"));
|
||||
driver.waitForElementToNotExist(By.tagName("mat-progress-bar"));
|
||||
}
|
||||
|
||||
private void selectRegistrar() throws InterruptedException {
|
||||
driver.findElement(By.cssSelector("div.console-app__registrar input")).click();
|
||||
Thread.sleep(200);
|
||||
driver.diffPage("selectorOpen");
|
||||
driver.findElement(By.cssSelector("div.mat-mdc-autocomplete-panel mat-option")).click();
|
||||
Thread.sleep(200);
|
||||
}
|
||||
}
|
||||
@@ -43,7 +43,7 @@ class DockerWebDriverExtension implements BeforeAllCallback, AfterAllCallback {
|
||||
private static URL getWebDriverUrl() {
|
||||
// TODO(#209): Find a way to automatically detect the version of docker image
|
||||
GenericContainer container =
|
||||
new GenericContainer("selenium/standalone-chrome:3.141.59-mercury")
|
||||
new GenericContainer("selenium/standalone-chrome:4.25")
|
||||
.withFileSystemBind("/dev/shm", "/dev/shm", BindMode.READ_WRITE)
|
||||
.withExposedPorts(CHROME_DRIVER_SERVICE_PORT)
|
||||
.waitingFor(Wait.forHttp("/").withStartupTimeout(Duration.of(20, ChronoUnit.SECONDS)));
|
||||
@@ -53,7 +53,7 @@ class DockerWebDriverExtension implements BeforeAllCallback, AfterAllCallback {
|
||||
url =
|
||||
new URL(
|
||||
String.format(
|
||||
"http://%s:%d/wd/hub",
|
||||
"http://%s:%d",
|
||||
container.getContainerIpAddress(),
|
||||
container.getMappedPort(CHROME_DRIVER_SERVICE_PORT)));
|
||||
} catch (MalformedURLException e) {
|
||||
@@ -65,7 +65,7 @@ class DockerWebDriverExtension implements BeforeAllCallback, AfterAllCallback {
|
||||
|
||||
@Override
|
||||
public void beforeAll(ExtensionContext context) {
|
||||
ChromeOptions chromeOptions = new ChromeOptions().setHeadless(true);
|
||||
ChromeOptions chromeOptions = new ChromeOptions().addArguments("--headless=new");
|
||||
webDriver = new RemoteWebDriver(WEB_DRIVER_URL, chromeOptions);
|
||||
}
|
||||
|
||||
|
||||
@@ -22,11 +22,13 @@ import com.google.common.collect.ImmutableMap;
|
||||
import google.registry.module.frontend.FrontendServlet;
|
||||
import google.registry.server.RegistryTestServer;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
import org.junitpioneer.jupiter.RetryingTest;
|
||||
import org.openqa.selenium.By;
|
||||
|
||||
/** Registrar Console Screenshot Differ tests. */
|
||||
@Disabled
|
||||
public class OteSetupConsoleScreenshotTest extends WebDriverTestCase {
|
||||
|
||||
@RegisterExtension
|
||||
|
||||
@@ -22,6 +22,7 @@ import static google.registry.util.NetworkUtils.pickUnusedPort;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.net.HostAndPort;
|
||||
import google.registry.model.console.GlobalRole;
|
||||
import google.registry.model.console.RegistrarRole;
|
||||
import google.registry.model.console.User;
|
||||
import google.registry.model.console.UserRoles;
|
||||
@@ -139,6 +140,15 @@ public final class TestServerExtension implements BeforeEachCallback, AfterEachC
|
||||
OidcTokenAuthenticationMechanism.setAuthResultForTesting(AuthResult.createUser(user));
|
||||
}
|
||||
|
||||
/** Sets the current user's global role. */
|
||||
public void setGlobalRole(GlobalRole globalRole) {
|
||||
user =
|
||||
user.asBuilder()
|
||||
.setUserRoles(new UserRoles.Builder().setGlobalRole(globalRole).build())
|
||||
.build();
|
||||
OidcTokenAuthenticationMechanism.setAuthResultForTesting(AuthResult.createUser(user));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TestServer#getUrl(String)
|
||||
*/
|
||||
@@ -231,11 +241,15 @@ public final class TestServerExtension implements BeforeEachCallback, AfterEachC
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setRoutes(ImmutableList<Route> routes) {
|
||||
checkArgument(!routes.isEmpty(), "Must include at least one route");
|
||||
this.routes = routes;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets the list of servlet {@link Route} objects for {@link TestServer}. */
|
||||
public Builder setRoutes(Route... routes) {
|
||||
checkArgument(routes.length > 0);
|
||||
this.routes = ImmutableList.copyOf(routes);
|
||||
return this;
|
||||
return setRoutes(ImmutableList.copyOf(routes));
|
||||
}
|
||||
|
||||
/** Sets an ordered list of fixtures that should be loaded on startup. */
|
||||
|
||||
@@ -52,7 +52,6 @@ public final class WebDriverPlusScreenDifferExtension
|
||||
implements BeforeEachCallback,
|
||||
AfterEachCallback,
|
||||
WebDriver,
|
||||
org.openqa.selenium.interactions.HasInputDevices,
|
||||
TakesScreenshot,
|
||||
JavascriptExecutor,
|
||||
HasCapabilities {
|
||||
@@ -72,7 +71,7 @@ public final class WebDriverPlusScreenDifferExtension
|
||||
|
||||
// Default size of the browser window when taking screenshot. Having a fixed size of window can
|
||||
// help make visual regression test deterministic.
|
||||
private static final Dimension DEFAULT_WINDOW_SIZE = new Dimension(1200, 2000);
|
||||
private static final Dimension DEFAULT_WINDOW_SIZE = new Dimension(1920, 1200);
|
||||
|
||||
private static final String GOLDENS_PATH =
|
||||
getResource(WebDriverPlusScreenDifferExtension.class, "goldens/chrome-linux").getFile();
|
||||
@@ -133,6 +132,16 @@ public final class WebDriverPlusScreenDifferExtension
|
||||
return waitForElementWithCondition(by, Predicates.alwaysTrue());
|
||||
}
|
||||
|
||||
/** Waits for the removal of an element (e.g. a loading bar). */
|
||||
void waitForElementToNotExist(By by) throws InterruptedException {
|
||||
while (true) {
|
||||
if (findElements(by).isEmpty()) {
|
||||
return;
|
||||
}
|
||||
Thread.sleep(WAIT_FOR_ELEMENTS_POLLING_INTERVAL_MS);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes an action and waits indefinitely for the replacement of an <em>existing</em> element.
|
||||
*/
|
||||
@@ -283,16 +292,6 @@ public final class WebDriverPlusScreenDifferExtension
|
||||
return driver.manage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public org.openqa.selenium.interactions.Keyboard getKeyboard() {
|
||||
return ((org.openqa.selenium.interactions.HasInputDevices) driver).getKeyboard();
|
||||
}
|
||||
|
||||
@Override
|
||||
public org.openqa.selenium.interactions.Mouse getMouse() {
|
||||
return ((org.openqa.selenium.interactions.HasInputDevices) driver).getMouse();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <X> X getScreenshotAs(OutputType<X> target) throws WebDriverException {
|
||||
return ((TakesScreenshot) driver).getScreenshotAs(target);
|
||||
|
||||
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 49 KiB |
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 132 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 133 KiB |
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 44 KiB |
|
After Width: | Height: | Size: 66 KiB |
|
After Width: | Height: | Size: 39 KiB |
|
After Width: | Height: | Size: 41 KiB |
|
After Width: | Height: | Size: 42 KiB |
|
After Width: | Height: | Size: 39 KiB |
|
After Width: | Height: | Size: 70 KiB |
|
After Width: | Height: | Size: 70 KiB |
|
After Width: | Height: | Size: 72 KiB |
|
After Width: | Height: | Size: 73 KiB |
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 51 KiB |
|
After Width: | Height: | Size: 51 KiB |
|
After Width: | Height: | Size: 69 KiB |
|
After Width: | Height: | Size: 70 KiB |
|
After Width: | Height: | Size: 39 KiB |
|
After Width: | Height: | Size: 73 KiB |
|
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 53 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 75 KiB After Width: | Height: | Size: 65 KiB |
|
Before Width: | Height: | Size: 84 KiB After Width: | Height: | Size: 80 KiB |
|
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 94 KiB After Width: | Height: | Size: 86 KiB |
|
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 95 KiB After Width: | Height: | Size: 87 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 9.9 KiB |
|
Before Width: | Height: | Size: 81 KiB After Width: | Height: | Size: 76 KiB |
|
Before Width: | Height: | Size: 81 KiB After Width: | Height: | Size: 76 KiB |
|
Before Width: | Height: | Size: 77 KiB After Width: | Height: | Size: 71 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 51 KiB |
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 61 KiB |
|
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 60 KiB |
|
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 75 KiB After Width: | Height: | Size: 69 KiB |
|
Before Width: | Height: | Size: 90 KiB After Width: | Height: | Size: 79 KiB |
|
Before Width: | Height: | Size: 99 KiB After Width: | Height: | Size: 86 KiB |
|
Before Width: | Height: | Size: 99 KiB After Width: | Height: | Size: 86 KiB |
|
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 99 KiB After Width: | Height: | Size: 86 KiB |
|
Before Width: | Height: | Size: 110 KiB After Width: | Height: | Size: 101 KiB |
|
Before Width: | Height: | Size: 110 KiB After Width: | Height: | Size: 96 KiB |
|
Before Width: | Height: | Size: 110 KiB After Width: | Height: | Size: 96 KiB |
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 45 KiB |
|
Before Width: | Height: | Size: 206 KiB After Width: | Height: | Size: 178 KiB |
|
Before Width: | Height: | Size: 206 KiB After Width: | Height: | Size: 176 KiB |
|
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 60 KiB |
|
Before Width: | Height: | Size: 150 KiB After Width: | Height: | Size: 128 KiB |
|
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 57 KiB |
|
Before Width: | Height: | Size: 65 KiB After Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 49 KiB |
|
Before Width: | Height: | Size: 65 KiB After Width: | Height: | Size: 55 KiB |
|
Before Width: | Height: | Size: 90 KiB After Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 97 KiB After Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 24 KiB |