diff --git a/.travis.yml b/.travis.yml index 879ab3d2c..8dee36eb7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,6 +28,10 @@ cache: - $HOME/.gradle/caches/ - $HOME/.gradle/wrapper/ +# Get Chrome binary for WebDriver tests +addons: + chrome: stable + env: # Disable fancy status information (looks bad on travis and exceeds logfile # quota) diff --git a/gradle/core/build.gradle b/gradle/core/build.gradle index 22bc7fe0d..0b7d96988 100644 --- a/gradle/core/build.gradle +++ b/gradle/core/build.gradle @@ -188,6 +188,7 @@ dependencies { compile deps['org.apache.beam:beam-sdks-java-extensions-google-cloud-platform-core'] compile deps['org.apache.beam:beam-sdks-java-io-google-cloud-platform'] maybeRuntime deps['org.apache.commons:commons-compress'] + testCompile deps['org.apache.commons:commons-text'] maybeRuntime deps['org.apache.ftpserver:ftplet-api'] testCompile deps['org.apache.ftpserver:ftplet-api'] maybeRuntime deps['org.apache.ftpserver:ftpserver-core'] @@ -216,6 +217,10 @@ dependencies { testCompile deps['org.mortbay.jetty:jetty'] compile deps['org.mortbay.jetty:servlet-api'] maybeRuntime deps['org.mortbay.jetty:jetty-util'] + testCompile deps['org.seleniumhq.selenium:selenium-api'] + testCompile deps['org.seleniumhq.selenium:selenium-chrome-driver'] + testCompile deps['org.seleniumhq.selenium:selenium-java'] + testCompile deps['org.seleniumhq.selenium:selenium-remote-driver'] maybeRuntime deps['org.slf4j:slf4j-api'] maybeRuntime deps['org.tukaani:xz'] maybeRuntime deps['org.xerial.snappy:snappy-java'] @@ -461,6 +466,11 @@ task stylesheetsToJavascript { sourceFiles << (cssSourceDir + "/" + it.name) } } + + // The css files have to be passed to the compiler in alphabetic order to + // avoid some flaky style issues + sourceFiles.sort() + cssCompile("${outputDir}/registrar_bin", false, sourceFiles) cssCompile("${outputDir}/registrar_dbg", true, sourceFiles) } @@ -485,13 +495,15 @@ task compileProdJS(type: JavaExec) { // compilation options closureArgs << "--compilation_level=ADVANCED" closureArgs << "--entry_point=goog:registry.registrar.main" - closureArgs << "--externs=${javaDir}/google/registry/ui/externs/json.js" + closureArgs << "--generate_exports" // manually include all the required js files closureArgs << "--js=${rootDir}/node_modules/google-closure-library/**.js" closureArgs << "--js=${rootDir}/node_modules/soyutils_usegoog.js" closureArgs << "--js=${resourcesDir}/google/registry/ui/css/registrar_bin.css.js" closureArgs << "--js=${javaDir}/google/registry/ui/js/**.js" + // TODO(shicong) Verify the compiled JS file works in Alpha + closureArgs << "--js=${javaDir}/google/registry/ui/externs/json.js" closureArgs << "--js=${generatedDir}/google/registry/ui/soy/**.js" args closureArgs } @@ -543,11 +555,42 @@ task outcastTest(type: Test) { maxParallelForks 5 } +import org.apache.tools.ant.taskdefs.condition.Os +import java.nio.file.Files +import java.nio.file.Paths +ext.getChromedriver = { + def chromedriverZipFileName + if (Os.isFamily(Os.FAMILY_UNIX)) { + chromedriverZipFileName = 'chromedriver_linux64.zip' + } else if (Os.isFamily(Os.FAMILY_MAC)) { + chromedriverZipFileName = 'chromedriver_mac64.zip' + } else if (Os.isFamily(Os.FAMILY_WINDOWS)) { + chromedriverZipFileName = 'chromedriver_win32.zip' + } else { + throw new RuntimeException("Unsupported OS: ${OperatingSystem.getDisplayName()}") + } + + def tempDir = Files.createTempDirectory("chromedriver-dir").toString() + + ant.get(src: 'https://chromedriver.storage.googleapis.com/LATEST_RELEASE', dest: tempDir) + def latestReleaseVersion = Paths.get(tempDir, 'LATEST_RELEASE').readLines().get(0) + ant.get(src: "https://chromedriver.storage.googleapis.com/${latestReleaseVersion}/${chromedriverZipFileName}", dest: tempDir) + ant.unzip(src: "${tempDir}/${chromedriverZipFileName}", dest: tempDir) + + def chromedriverFile = new File(tempDir, 'chromedriver') + chromedriverFile.setExecutable(true) + + return chromedriverFile.getCanonicalPath() +} + test { // Common exclude pattern. See README in parent directory for explanation. exclude "**/*TestCase.*", "**/*TestSuite.*" exclude fragileTestPatterns exclude outcastTestPatterns + if (rootProject.hasProperty("excludeWebDriverTests")) { + exclude "**/webdriver/*" + } // Run every test class in its own process. // Uncomment to unblock build while troubleshooting inexplicable test errors. @@ -556,6 +599,10 @@ test { // Sets the maximum number of test executors that may exist at the same time. maxParallelForks 5 + + // Set system property for Webdriver + systemProperty 'webdriver.chrome.driver', project.getChromedriver() + }.dependsOn(fragileTest, outcastTest) task nomulus(type: Jar) { diff --git a/gradle/core/gradle/dependency-locks/testCompile.lockfile b/gradle/core/gradle/dependency-locks/testCompile.lockfile index 317181813..cf81a057a 100644 --- a/gradle/core/gradle/dependency-locks/testCompile.lockfile +++ b/gradle/core/gradle/dependency-locks/testCompile.lockfile @@ -107,8 +107,9 @@ com.googlecode.java-diff-utils:diffutils:1.3.0 com.googlecode.json-simple:json-simple:1.1.1 com.ibm.icu:icu4j:57.1 com.jcraft:jsch:0.1.53 +com.squareup.okhttp3:okhttp:3.11.0 com.squareup.okhttp:okhttp:2.5.0 -com.squareup.okio:okio:1.6.0 +com.squareup.okio:okio:1.14.0 com.thoughtworks.paranamer:paranamer:2.7 commons-codec:commons-codec:1.10 commons-logging:commons-logging:1.2 @@ -151,6 +152,7 @@ javax.xml.bind:jaxb-api:2.3.0 jline:jline:1.0 joda-time:joda-time:2.9.2 junit:junit:4.12 +net.bytebuddy:byte-buddy:1.8.15 org.apache.avro:avro:1.8.2 org.apache.beam:beam-runners-direct-java:2.2.0 org.apache.beam:beam-runners-google-cloud-dataflow-java:2.1.0 @@ -160,6 +162,9 @@ org.apache.beam:beam-sdks-java-extensions-google-cloud-platform-core:2.2.0 org.apache.beam:beam-sdks-java-extensions-protobuf:2.2.0 org.apache.beam:beam-sdks-java-io-google-cloud-platform:2.2.0 org.apache.commons:commons-compress:1.8.1 +org.apache.commons:commons-exec:1.3 +org.apache.commons:commons-lang3:3.8.1 +org.apache.commons:commons-text:1.6 org.apache.ftpserver:ftplet-api:1.0.6 org.apache.ftpserver:ftpserver-core:1.0.6 org.apache.httpcomponents:httpclient:4.5.5 @@ -194,6 +199,16 @@ org.ow2.asm:asm-commons:6.0 org.ow2.asm:asm-tree:6.0 org.ow2.asm:asm-util:6.0 org.ow2.asm:asm:6.0 +org.seleniumhq.selenium:selenium-api:3.141.59 +org.seleniumhq.selenium:selenium-chrome-driver:3.141.59 +org.seleniumhq.selenium:selenium-edge-driver:3.141.59 +org.seleniumhq.selenium:selenium-firefox-driver:3.141.59 +org.seleniumhq.selenium:selenium-ie-driver:3.141.59 +org.seleniumhq.selenium:selenium-java:3.141.59 +org.seleniumhq.selenium:selenium-opera-driver:3.141.59 +org.seleniumhq.selenium:selenium-remote-driver:3.141.59 +org.seleniumhq.selenium:selenium-safari-driver:3.141.59 +org.seleniumhq.selenium:selenium-support:3.141.59 org.slf4j:slf4j-api:1.7.25 org.threeten:threetenbp:1.3.3 org.tukaani:xz:1.5 diff --git a/gradle/core/gradle/dependency-locks/testCompileClasspath.lockfile b/gradle/core/gradle/dependency-locks/testCompileClasspath.lockfile index 6fc02cbbf..463e7131b 100644 --- a/gradle/core/gradle/dependency-locks/testCompileClasspath.lockfile +++ b/gradle/core/gradle/dependency-locks/testCompileClasspath.lockfile @@ -106,6 +106,8 @@ com.googlecode.java-diff-utils:diffutils:1.3.0 com.googlecode.json-simple:json-simple:1.1.1 com.ibm.icu:icu4j:57.1 com.jcraft:jsch:0.1.53 +com.squareup.okhttp3:okhttp:3.11.0 +com.squareup.okio:okio:1.14.0 com.thoughtworks.paranamer:paranamer:2.7 commons-codec:commons-codec:1.10 commons-logging:commons-logging:1.2 @@ -145,6 +147,7 @@ javax.xml.bind:jaxb-api:2.3.0 jline:jline:1.0 joda-time:joda-time:2.9.2 junit:junit:4.12 +net.bytebuddy:byte-buddy:1.8.15 org.apache.avro:avro:1.8.2 org.apache.beam:beam-runners-direct-java:2.2.0 org.apache.beam:beam-runners-google-cloud-dataflow-java:2.1.0 @@ -154,6 +157,9 @@ org.apache.beam:beam-sdks-java-extensions-google-cloud-platform-core:2.2.0 org.apache.beam:beam-sdks-java-extensions-protobuf:2.2.0 org.apache.beam:beam-sdks-java-io-google-cloud-platform:2.2.0 org.apache.commons:commons-compress:1.8.1 +org.apache.commons:commons-exec:1.3 +org.apache.commons:commons-lang3:3.8.1 +org.apache.commons:commons-text:1.6 org.apache.ftpserver:ftplet-api:1.0.6 org.apache.ftpserver:ftpserver-core:1.0.6 org.apache.httpcomponents:httpclient:4.5.5 @@ -188,6 +194,16 @@ org.ow2.asm:asm-commons:6.0 org.ow2.asm:asm-tree:6.0 org.ow2.asm:asm-util:6.0 org.ow2.asm:asm:6.0 +org.seleniumhq.selenium:selenium-api:3.141.59 +org.seleniumhq.selenium:selenium-chrome-driver:3.141.59 +org.seleniumhq.selenium:selenium-edge-driver:3.141.59 +org.seleniumhq.selenium:selenium-firefox-driver:3.141.59 +org.seleniumhq.selenium:selenium-ie-driver:3.141.59 +org.seleniumhq.selenium:selenium-java:3.141.59 +org.seleniumhq.selenium:selenium-opera-driver:3.141.59 +org.seleniumhq.selenium:selenium-remote-driver:3.141.59 +org.seleniumhq.selenium:selenium-safari-driver:3.141.59 +org.seleniumhq.selenium:selenium-support:3.141.59 org.slf4j:slf4j-api:1.7.25 org.threeten:threetenbp:1.3.3 org.tukaani:xz:1.5 diff --git a/gradle/core/gradle/dependency-locks/testRuntime.lockfile b/gradle/core/gradle/dependency-locks/testRuntime.lockfile index fbbe9e934..a90ec8399 100644 --- a/gradle/core/gradle/dependency-locks/testRuntime.lockfile +++ b/gradle/core/gradle/dependency-locks/testRuntime.lockfile @@ -108,8 +108,9 @@ com.googlecode.java-diff-utils:diffutils:1.3.0 com.googlecode.json-simple:json-simple:1.1.1 com.ibm.icu:icu4j:57.1 com.jcraft:jsch:0.1.53 +com.squareup.okhttp3:okhttp:3.11.0 com.squareup.okhttp:okhttp:2.5.0 -com.squareup.okio:okio:1.6.0 +com.squareup.okio:okio:1.14.0 com.sun.istack:istack-commons-runtime:3.0.5 com.sun.xml.fastinfoset:FastInfoset:1.2.13 com.thoughtworks.paranamer:paranamer:2.7 @@ -154,6 +155,7 @@ javax.xml.bind:jaxb-api:2.3.0 jline:jline:1.0 joda-time:joda-time:2.9.2 junit:junit:4.12 +net.bytebuddy:byte-buddy:1.8.15 org.apache.avro:avro:1.8.2 org.apache.beam:beam-runners-direct-java:2.2.0 org.apache.beam:beam-runners-google-cloud-dataflow-java:2.1.0 @@ -163,6 +165,9 @@ org.apache.beam:beam-sdks-java-extensions-google-cloud-platform-core:2.2.0 org.apache.beam:beam-sdks-java-extensions-protobuf:2.2.0 org.apache.beam:beam-sdks-java-io-google-cloud-platform:2.2.0 org.apache.commons:commons-compress:1.8.1 +org.apache.commons:commons-exec:1.3 +org.apache.commons:commons-lang3:3.8.1 +org.apache.commons:commons-text:1.6 org.apache.ftpserver:ftplet-api:1.0.6 org.apache.ftpserver:ftpserver-core:1.0.6 org.apache.httpcomponents:httpclient:4.5.5 @@ -201,6 +206,16 @@ org.ow2.asm:asm-commons:6.0 org.ow2.asm:asm-tree:6.0 org.ow2.asm:asm-util:6.0 org.ow2.asm:asm:6.0 +org.seleniumhq.selenium:selenium-api:3.141.59 +org.seleniumhq.selenium:selenium-chrome-driver:3.141.59 +org.seleniumhq.selenium:selenium-edge-driver:3.141.59 +org.seleniumhq.selenium:selenium-firefox-driver:3.141.59 +org.seleniumhq.selenium:selenium-ie-driver:3.141.59 +org.seleniumhq.selenium:selenium-java:3.141.59 +org.seleniumhq.selenium:selenium-opera-driver:3.141.59 +org.seleniumhq.selenium:selenium-remote-driver:3.141.59 +org.seleniumhq.selenium:selenium-safari-driver:3.141.59 +org.seleniumhq.selenium:selenium-support:3.141.59 org.slf4j:slf4j-api:1.7.25 org.threeten:threetenbp:1.3.3 org.tukaani:xz:1.5 diff --git a/gradle/core/gradle/dependency-locks/testRuntimeClasspath.lockfile b/gradle/core/gradle/dependency-locks/testRuntimeClasspath.lockfile index fbbe9e934..a90ec8399 100644 --- a/gradle/core/gradle/dependency-locks/testRuntimeClasspath.lockfile +++ b/gradle/core/gradle/dependency-locks/testRuntimeClasspath.lockfile @@ -108,8 +108,9 @@ com.googlecode.java-diff-utils:diffutils:1.3.0 com.googlecode.json-simple:json-simple:1.1.1 com.ibm.icu:icu4j:57.1 com.jcraft:jsch:0.1.53 +com.squareup.okhttp3:okhttp:3.11.0 com.squareup.okhttp:okhttp:2.5.0 -com.squareup.okio:okio:1.6.0 +com.squareup.okio:okio:1.14.0 com.sun.istack:istack-commons-runtime:3.0.5 com.sun.xml.fastinfoset:FastInfoset:1.2.13 com.thoughtworks.paranamer:paranamer:2.7 @@ -154,6 +155,7 @@ javax.xml.bind:jaxb-api:2.3.0 jline:jline:1.0 joda-time:joda-time:2.9.2 junit:junit:4.12 +net.bytebuddy:byte-buddy:1.8.15 org.apache.avro:avro:1.8.2 org.apache.beam:beam-runners-direct-java:2.2.0 org.apache.beam:beam-runners-google-cloud-dataflow-java:2.1.0 @@ -163,6 +165,9 @@ org.apache.beam:beam-sdks-java-extensions-google-cloud-platform-core:2.2.0 org.apache.beam:beam-sdks-java-extensions-protobuf:2.2.0 org.apache.beam:beam-sdks-java-io-google-cloud-platform:2.2.0 org.apache.commons:commons-compress:1.8.1 +org.apache.commons:commons-exec:1.3 +org.apache.commons:commons-lang3:3.8.1 +org.apache.commons:commons-text:1.6 org.apache.ftpserver:ftplet-api:1.0.6 org.apache.ftpserver:ftpserver-core:1.0.6 org.apache.httpcomponents:httpclient:4.5.5 @@ -201,6 +206,16 @@ org.ow2.asm:asm-commons:6.0 org.ow2.asm:asm-tree:6.0 org.ow2.asm:asm-util:6.0 org.ow2.asm:asm:6.0 +org.seleniumhq.selenium:selenium-api:3.141.59 +org.seleniumhq.selenium:selenium-chrome-driver:3.141.59 +org.seleniumhq.selenium:selenium-edge-driver:3.141.59 +org.seleniumhq.selenium:selenium-firefox-driver:3.141.59 +org.seleniumhq.selenium:selenium-ie-driver:3.141.59 +org.seleniumhq.selenium:selenium-java:3.141.59 +org.seleniumhq.selenium:selenium-opera-driver:3.141.59 +org.seleniumhq.selenium:selenium-remote-driver:3.141.59 +org.seleniumhq.selenium:selenium-safari-driver:3.141.59 +org.seleniumhq.selenium:selenium-support:3.141.59 org.slf4j:slf4j-api:1.7.25 org.threeten:threetenbp:1.3.3 org.tukaani:xz:1.5 diff --git a/gradle/dependencies.gradle b/gradle/dependencies.gradle index b035c217b..2246d96b6 100644 --- a/gradle/dependencies.gradle +++ b/gradle/dependencies.gradle @@ -112,6 +112,7 @@ ext { 'org.apache.beam:beam-sdks-java-extensions-google-cloud-platform-core:2.1.0', 'org.apache.beam:beam-sdks-java-io-google-cloud-platform:2.2.0', 'org.apache.commons:commons-compress:1.8.1', + 'org.apache.commons:commons-text:1.6', 'org.apache.ftpserver:ftplet-api:1.0.6', 'org.apache.ftpserver:ftpserver-core:1.0.6', 'org.apache.httpcomponents:httpclient:4.5.2', @@ -138,6 +139,10 @@ ext { 'org.mortbay.jetty:jetty:6.1.26', 'org.mortbay.jetty:jetty-util:6.1.26', 'org.mortbay.jetty:servlet-api:2.5-20081211', + 'org.seleniumhq.selenium:selenium-api:3.141.59', + 'org.seleniumhq.selenium:selenium-chrome-driver:3.141.59', + 'org.seleniumhq.selenium:selenium-java:3.141.59', + 'org.seleniumhq.selenium:selenium-remote-driver:3.141.59', 'org.slf4j:slf4j-api:1.7.16', 'org.tukaani:xz:1.5', 'org.xerial.snappy:snappy-java:1.1.4-M3', diff --git a/gradle/proxy/gradle/dependency-locks/testCompile.lockfile b/gradle/proxy/gradle/dependency-locks/testCompile.lockfile index 33f43123d..3ce5e4ee8 100644 --- a/gradle/proxy/gradle/dependency-locks/testCompile.lockfile +++ b/gradle/proxy/gradle/dependency-locks/testCompile.lockfile @@ -108,8 +108,9 @@ com.googlecode.java-diff-utils:diffutils:1.3.0 com.googlecode.json-simple:json-simple:1.1.1 com.ibm.icu:icu4j:57.1 com.jcraft:jsch:0.1.53 +com.squareup.okhttp3:okhttp:3.11.0 com.squareup.okhttp:okhttp:2.5.0 -com.squareup.okio:okio:1.6.0 +com.squareup.okio:okio:1.14.0 com.sun.istack:istack-commons-runtime:3.0.5 com.sun.xml.fastinfoset:FastInfoset:1.2.13 com.thoughtworks.paranamer:paranamer:2.7 @@ -154,6 +155,7 @@ javax.xml.bind:jaxb-api:2.3.0 jline:jline:1.0 joda-time:joda-time:2.9.2 junit:junit:4.12 +net.bytebuddy:byte-buddy:1.8.15 org.apache.avro:avro:1.8.2 org.apache.beam:beam-runners-direct-java:2.2.0 org.apache.beam:beam-runners-google-cloud-dataflow-java:2.1.0 @@ -163,6 +165,9 @@ org.apache.beam:beam-sdks-java-extensions-google-cloud-platform-core:2.2.0 org.apache.beam:beam-sdks-java-extensions-protobuf:2.2.0 org.apache.beam:beam-sdks-java-io-google-cloud-platform:2.2.0 org.apache.commons:commons-compress:1.8.1 +org.apache.commons:commons-exec:1.3 +org.apache.commons:commons-lang3:3.8.1 +org.apache.commons:commons-text:1.6 org.apache.ftpserver:ftplet-api:1.0.6 org.apache.ftpserver:ftpserver-core:1.0.6 org.apache.httpcomponents:httpclient:4.5.5 @@ -201,6 +206,16 @@ org.ow2.asm:asm-commons:6.0 org.ow2.asm:asm-tree:6.0 org.ow2.asm:asm-util:6.0 org.ow2.asm:asm:6.0 +org.seleniumhq.selenium:selenium-api:3.141.59 +org.seleniumhq.selenium:selenium-chrome-driver:3.141.59 +org.seleniumhq.selenium:selenium-edge-driver:3.141.59 +org.seleniumhq.selenium:selenium-firefox-driver:3.141.59 +org.seleniumhq.selenium:selenium-ie-driver:3.141.59 +org.seleniumhq.selenium:selenium-java:3.141.59 +org.seleniumhq.selenium:selenium-opera-driver:3.141.59 +org.seleniumhq.selenium:selenium-remote-driver:3.141.59 +org.seleniumhq.selenium:selenium-safari-driver:3.141.59 +org.seleniumhq.selenium:selenium-support:3.141.59 org.slf4j:slf4j-api:1.7.25 org.threeten:threetenbp:1.3.3 org.tukaani:xz:1.5 diff --git a/gradle/proxy/gradle/dependency-locks/testCompileClasspath.lockfile b/gradle/proxy/gradle/dependency-locks/testCompileClasspath.lockfile index d25827385..be3e9def6 100644 --- a/gradle/proxy/gradle/dependency-locks/testCompileClasspath.lockfile +++ b/gradle/proxy/gradle/dependency-locks/testCompileClasspath.lockfile @@ -107,6 +107,8 @@ com.googlecode.java-diff-utils:diffutils:1.3.0 com.googlecode.json-simple:json-simple:1.1.1 com.ibm.icu:icu4j:57.1 com.jcraft:jsch:0.1.53 +com.squareup.okhttp3:okhttp:3.11.0 +com.squareup.okio:okio:1.14.0 com.sun.istack:istack-commons-runtime:3.0.5 com.sun.xml.fastinfoset:FastInfoset:1.2.13 com.thoughtworks.paranamer:paranamer:2.7 @@ -148,6 +150,7 @@ javax.xml.bind:jaxb-api:2.3.0 jline:jline:1.0 joda-time:joda-time:2.9.2 junit:junit:4.12 +net.bytebuddy:byte-buddy:1.8.15 org.apache.avro:avro:1.8.2 org.apache.beam:beam-runners-direct-java:2.2.0 org.apache.beam:beam-runners-google-cloud-dataflow-java:2.1.0 @@ -157,6 +160,9 @@ org.apache.beam:beam-sdks-java-extensions-google-cloud-platform-core:2.2.0 org.apache.beam:beam-sdks-java-extensions-protobuf:2.2.0 org.apache.beam:beam-sdks-java-io-google-cloud-platform:2.2.0 org.apache.commons:commons-compress:1.8.1 +org.apache.commons:commons-exec:1.3 +org.apache.commons:commons-lang3:3.8.1 +org.apache.commons:commons-text:1.6 org.apache.ftpserver:ftplet-api:1.0.6 org.apache.ftpserver:ftpserver-core:1.0.6 org.apache.httpcomponents:httpclient:4.5.5 @@ -195,6 +201,16 @@ org.ow2.asm:asm-commons:6.0 org.ow2.asm:asm-tree:6.0 org.ow2.asm:asm-util:6.0 org.ow2.asm:asm:6.0 +org.seleniumhq.selenium:selenium-api:3.141.59 +org.seleniumhq.selenium:selenium-chrome-driver:3.141.59 +org.seleniumhq.selenium:selenium-edge-driver:3.141.59 +org.seleniumhq.selenium:selenium-firefox-driver:3.141.59 +org.seleniumhq.selenium:selenium-ie-driver:3.141.59 +org.seleniumhq.selenium:selenium-java:3.141.59 +org.seleniumhq.selenium:selenium-opera-driver:3.141.59 +org.seleniumhq.selenium:selenium-remote-driver:3.141.59 +org.seleniumhq.selenium:selenium-safari-driver:3.141.59 +org.seleniumhq.selenium:selenium-support:3.141.59 org.slf4j:slf4j-api:1.7.25 org.threeten:threetenbp:1.3.3 org.tukaani:xz:1.5 diff --git a/gradle/proxy/gradle/dependency-locks/testRuntime.lockfile b/gradle/proxy/gradle/dependency-locks/testRuntime.lockfile index 4f665ae64..0c8a96266 100644 --- a/gradle/proxy/gradle/dependency-locks/testRuntime.lockfile +++ b/gradle/proxy/gradle/dependency-locks/testRuntime.lockfile @@ -108,8 +108,9 @@ com.googlecode.java-diff-utils:diffutils:1.3.0 com.googlecode.json-simple:json-simple:1.1.1 com.ibm.icu:icu4j:57.1 com.jcraft:jsch:0.1.53 +com.squareup.okhttp3:okhttp:3.11.0 com.squareup.okhttp:okhttp:2.5.0 -com.squareup.okio:okio:1.6.0 +com.squareup.okio:okio:1.14.0 com.sun.istack:istack-commons-runtime:3.0.5 com.sun.xml.fastinfoset:FastInfoset:1.2.13 com.thoughtworks.paranamer:paranamer:2.7 @@ -154,6 +155,7 @@ javax.xml.bind:jaxb-api:2.3.0 jline:jline:1.0 joda-time:joda-time:2.9.2 junit:junit:4.12 +net.bytebuddy:byte-buddy:1.8.15 org.apache.avro:avro:1.8.2 org.apache.beam:beam-runners-direct-java:2.2.0 org.apache.beam:beam-runners-google-cloud-dataflow-java:2.1.0 @@ -163,6 +165,9 @@ org.apache.beam:beam-sdks-java-extensions-google-cloud-platform-core:2.2.0 org.apache.beam:beam-sdks-java-extensions-protobuf:2.2.0 org.apache.beam:beam-sdks-java-io-google-cloud-platform:2.2.0 org.apache.commons:commons-compress:1.8.1 +org.apache.commons:commons-exec:1.3 +org.apache.commons:commons-lang3:3.8.1 +org.apache.commons:commons-text:1.6 org.apache.ftpserver:ftplet-api:1.0.6 org.apache.ftpserver:ftpserver-core:1.0.6 org.apache.httpcomponents:httpclient:4.5.5 @@ -201,6 +206,16 @@ org.ow2.asm:asm-commons:6.0 org.ow2.asm:asm-tree:6.0 org.ow2.asm:asm-util:6.0 org.ow2.asm:asm:6.0 +org.seleniumhq.selenium:selenium-api:3.141.59 +org.seleniumhq.selenium:selenium-chrome-driver:3.141.59 +org.seleniumhq.selenium:selenium-edge-driver:3.141.59 +org.seleniumhq.selenium:selenium-firefox-driver:3.141.59 +org.seleniumhq.selenium:selenium-ie-driver:3.141.59 +org.seleniumhq.selenium:selenium-java:3.141.59 +org.seleniumhq.selenium:selenium-opera-driver:3.141.59 +org.seleniumhq.selenium:selenium-remote-driver:3.141.59 +org.seleniumhq.selenium:selenium-safari-driver:3.141.59 +org.seleniumhq.selenium:selenium-support:3.141.59 org.slf4j:slf4j-api:1.7.25 org.threeten:threetenbp:1.3.3 org.tukaani:xz:1.5 diff --git a/gradle/proxy/gradle/dependency-locks/testRuntimeClasspath.lockfile b/gradle/proxy/gradle/dependency-locks/testRuntimeClasspath.lockfile index 4f665ae64..0c8a96266 100644 --- a/gradle/proxy/gradle/dependency-locks/testRuntimeClasspath.lockfile +++ b/gradle/proxy/gradle/dependency-locks/testRuntimeClasspath.lockfile @@ -108,8 +108,9 @@ com.googlecode.java-diff-utils:diffutils:1.3.0 com.googlecode.json-simple:json-simple:1.1.1 com.ibm.icu:icu4j:57.1 com.jcraft:jsch:0.1.53 +com.squareup.okhttp3:okhttp:3.11.0 com.squareup.okhttp:okhttp:2.5.0 -com.squareup.okio:okio:1.6.0 +com.squareup.okio:okio:1.14.0 com.sun.istack:istack-commons-runtime:3.0.5 com.sun.xml.fastinfoset:FastInfoset:1.2.13 com.thoughtworks.paranamer:paranamer:2.7 @@ -154,6 +155,7 @@ javax.xml.bind:jaxb-api:2.3.0 jline:jline:1.0 joda-time:joda-time:2.9.2 junit:junit:4.12 +net.bytebuddy:byte-buddy:1.8.15 org.apache.avro:avro:1.8.2 org.apache.beam:beam-runners-direct-java:2.2.0 org.apache.beam:beam-runners-google-cloud-dataflow-java:2.1.0 @@ -163,6 +165,9 @@ org.apache.beam:beam-sdks-java-extensions-google-cloud-platform-core:2.2.0 org.apache.beam:beam-sdks-java-extensions-protobuf:2.2.0 org.apache.beam:beam-sdks-java-io-google-cloud-platform:2.2.0 org.apache.commons:commons-compress:1.8.1 +org.apache.commons:commons-exec:1.3 +org.apache.commons:commons-lang3:3.8.1 +org.apache.commons:commons-text:1.6 org.apache.ftpserver:ftplet-api:1.0.6 org.apache.ftpserver:ftpserver-core:1.0.6 org.apache.httpcomponents:httpclient:4.5.5 @@ -201,6 +206,16 @@ org.ow2.asm:asm-commons:6.0 org.ow2.asm:asm-tree:6.0 org.ow2.asm:asm-util:6.0 org.ow2.asm:asm:6.0 +org.seleniumhq.selenium:selenium-api:3.141.59 +org.seleniumhq.selenium:selenium-chrome-driver:3.141.59 +org.seleniumhq.selenium:selenium-edge-driver:3.141.59 +org.seleniumhq.selenium:selenium-firefox-driver:3.141.59 +org.seleniumhq.selenium:selenium-ie-driver:3.141.59 +org.seleniumhq.selenium:selenium-java:3.141.59 +org.seleniumhq.selenium:selenium-opera-driver:3.141.59 +org.seleniumhq.selenium:selenium-remote-driver:3.141.59 +org.seleniumhq.selenium:selenium-safari-driver:3.141.59 +org.seleniumhq.selenium:selenium-support:3.141.59 org.slf4j:slf4j-api:1.7.25 org.threeten:threetenbp:1.3.3 org.tukaani:xz:1.5 diff --git a/gradle/util/gradle/dependency-locks/testCompile.lockfile b/gradle/util/gradle/dependency-locks/testCompile.lockfile index fbbe9e934..a90ec8399 100644 --- a/gradle/util/gradle/dependency-locks/testCompile.lockfile +++ b/gradle/util/gradle/dependency-locks/testCompile.lockfile @@ -108,8 +108,9 @@ com.googlecode.java-diff-utils:diffutils:1.3.0 com.googlecode.json-simple:json-simple:1.1.1 com.ibm.icu:icu4j:57.1 com.jcraft:jsch:0.1.53 +com.squareup.okhttp3:okhttp:3.11.0 com.squareup.okhttp:okhttp:2.5.0 -com.squareup.okio:okio:1.6.0 +com.squareup.okio:okio:1.14.0 com.sun.istack:istack-commons-runtime:3.0.5 com.sun.xml.fastinfoset:FastInfoset:1.2.13 com.thoughtworks.paranamer:paranamer:2.7 @@ -154,6 +155,7 @@ javax.xml.bind:jaxb-api:2.3.0 jline:jline:1.0 joda-time:joda-time:2.9.2 junit:junit:4.12 +net.bytebuddy:byte-buddy:1.8.15 org.apache.avro:avro:1.8.2 org.apache.beam:beam-runners-direct-java:2.2.0 org.apache.beam:beam-runners-google-cloud-dataflow-java:2.1.0 @@ -163,6 +165,9 @@ org.apache.beam:beam-sdks-java-extensions-google-cloud-platform-core:2.2.0 org.apache.beam:beam-sdks-java-extensions-protobuf:2.2.0 org.apache.beam:beam-sdks-java-io-google-cloud-platform:2.2.0 org.apache.commons:commons-compress:1.8.1 +org.apache.commons:commons-exec:1.3 +org.apache.commons:commons-lang3:3.8.1 +org.apache.commons:commons-text:1.6 org.apache.ftpserver:ftplet-api:1.0.6 org.apache.ftpserver:ftpserver-core:1.0.6 org.apache.httpcomponents:httpclient:4.5.5 @@ -201,6 +206,16 @@ org.ow2.asm:asm-commons:6.0 org.ow2.asm:asm-tree:6.0 org.ow2.asm:asm-util:6.0 org.ow2.asm:asm:6.0 +org.seleniumhq.selenium:selenium-api:3.141.59 +org.seleniumhq.selenium:selenium-chrome-driver:3.141.59 +org.seleniumhq.selenium:selenium-edge-driver:3.141.59 +org.seleniumhq.selenium:selenium-firefox-driver:3.141.59 +org.seleniumhq.selenium:selenium-ie-driver:3.141.59 +org.seleniumhq.selenium:selenium-java:3.141.59 +org.seleniumhq.selenium:selenium-opera-driver:3.141.59 +org.seleniumhq.selenium:selenium-remote-driver:3.141.59 +org.seleniumhq.selenium:selenium-safari-driver:3.141.59 +org.seleniumhq.selenium:selenium-support:3.141.59 org.slf4j:slf4j-api:1.7.25 org.threeten:threetenbp:1.3.3 org.tukaani:xz:1.5 diff --git a/gradle/util/gradle/dependency-locks/testCompileClasspath.lockfile b/gradle/util/gradle/dependency-locks/testCompileClasspath.lockfile index ba2addde4..87248c47c 100644 --- a/gradle/util/gradle/dependency-locks/testCompileClasspath.lockfile +++ b/gradle/util/gradle/dependency-locks/testCompileClasspath.lockfile @@ -107,6 +107,8 @@ com.googlecode.java-diff-utils:diffutils:1.3.0 com.googlecode.json-simple:json-simple:1.1.1 com.ibm.icu:icu4j:57.1 com.jcraft:jsch:0.1.53 +com.squareup.okhttp3:okhttp:3.11.0 +com.squareup.okio:okio:1.14.0 com.sun.istack:istack-commons-runtime:3.0.5 com.sun.xml.fastinfoset:FastInfoset:1.2.13 com.thoughtworks.paranamer:paranamer:2.7 @@ -148,6 +150,7 @@ javax.xml.bind:jaxb-api:2.3.0 jline:jline:1.0 joda-time:joda-time:2.9.2 junit:junit:4.12 +net.bytebuddy:byte-buddy:1.8.15 org.apache.avro:avro:1.8.2 org.apache.beam:beam-runners-direct-java:2.2.0 org.apache.beam:beam-runners-google-cloud-dataflow-java:2.1.0 @@ -157,6 +160,9 @@ org.apache.beam:beam-sdks-java-extensions-google-cloud-platform-core:2.2.0 org.apache.beam:beam-sdks-java-extensions-protobuf:2.2.0 org.apache.beam:beam-sdks-java-io-google-cloud-platform:2.2.0 org.apache.commons:commons-compress:1.8.1 +org.apache.commons:commons-exec:1.3 +org.apache.commons:commons-lang3:3.8.1 +org.apache.commons:commons-text:1.6 org.apache.ftpserver:ftplet-api:1.0.6 org.apache.ftpserver:ftpserver-core:1.0.6 org.apache.httpcomponents:httpclient:4.5.5 @@ -195,6 +201,16 @@ org.ow2.asm:asm-commons:6.0 org.ow2.asm:asm-tree:6.0 org.ow2.asm:asm-util:6.0 org.ow2.asm:asm:6.0 +org.seleniumhq.selenium:selenium-api:3.141.59 +org.seleniumhq.selenium:selenium-chrome-driver:3.141.59 +org.seleniumhq.selenium:selenium-edge-driver:3.141.59 +org.seleniumhq.selenium:selenium-firefox-driver:3.141.59 +org.seleniumhq.selenium:selenium-ie-driver:3.141.59 +org.seleniumhq.selenium:selenium-java:3.141.59 +org.seleniumhq.selenium:selenium-opera-driver:3.141.59 +org.seleniumhq.selenium:selenium-remote-driver:3.141.59 +org.seleniumhq.selenium:selenium-safari-driver:3.141.59 +org.seleniumhq.selenium:selenium-support:3.141.59 org.slf4j:slf4j-api:1.7.25 org.threeten:threetenbp:1.3.3 org.tukaani:xz:1.5 diff --git a/gradle/util/gradle/dependency-locks/testRuntime.lockfile b/gradle/util/gradle/dependency-locks/testRuntime.lockfile index fbbe9e934..a90ec8399 100644 --- a/gradle/util/gradle/dependency-locks/testRuntime.lockfile +++ b/gradle/util/gradle/dependency-locks/testRuntime.lockfile @@ -108,8 +108,9 @@ com.googlecode.java-diff-utils:diffutils:1.3.0 com.googlecode.json-simple:json-simple:1.1.1 com.ibm.icu:icu4j:57.1 com.jcraft:jsch:0.1.53 +com.squareup.okhttp3:okhttp:3.11.0 com.squareup.okhttp:okhttp:2.5.0 -com.squareup.okio:okio:1.6.0 +com.squareup.okio:okio:1.14.0 com.sun.istack:istack-commons-runtime:3.0.5 com.sun.xml.fastinfoset:FastInfoset:1.2.13 com.thoughtworks.paranamer:paranamer:2.7 @@ -154,6 +155,7 @@ javax.xml.bind:jaxb-api:2.3.0 jline:jline:1.0 joda-time:joda-time:2.9.2 junit:junit:4.12 +net.bytebuddy:byte-buddy:1.8.15 org.apache.avro:avro:1.8.2 org.apache.beam:beam-runners-direct-java:2.2.0 org.apache.beam:beam-runners-google-cloud-dataflow-java:2.1.0 @@ -163,6 +165,9 @@ org.apache.beam:beam-sdks-java-extensions-google-cloud-platform-core:2.2.0 org.apache.beam:beam-sdks-java-extensions-protobuf:2.2.0 org.apache.beam:beam-sdks-java-io-google-cloud-platform:2.2.0 org.apache.commons:commons-compress:1.8.1 +org.apache.commons:commons-exec:1.3 +org.apache.commons:commons-lang3:3.8.1 +org.apache.commons:commons-text:1.6 org.apache.ftpserver:ftplet-api:1.0.6 org.apache.ftpserver:ftpserver-core:1.0.6 org.apache.httpcomponents:httpclient:4.5.5 @@ -201,6 +206,16 @@ org.ow2.asm:asm-commons:6.0 org.ow2.asm:asm-tree:6.0 org.ow2.asm:asm-util:6.0 org.ow2.asm:asm:6.0 +org.seleniumhq.selenium:selenium-api:3.141.59 +org.seleniumhq.selenium:selenium-chrome-driver:3.141.59 +org.seleniumhq.selenium:selenium-edge-driver:3.141.59 +org.seleniumhq.selenium:selenium-firefox-driver:3.141.59 +org.seleniumhq.selenium:selenium-ie-driver:3.141.59 +org.seleniumhq.selenium:selenium-java:3.141.59 +org.seleniumhq.selenium:selenium-opera-driver:3.141.59 +org.seleniumhq.selenium:selenium-remote-driver:3.141.59 +org.seleniumhq.selenium:selenium-safari-driver:3.141.59 +org.seleniumhq.selenium:selenium-support:3.141.59 org.slf4j:slf4j-api:1.7.25 org.threeten:threetenbp:1.3.3 org.tukaani:xz:1.5 diff --git a/gradle/util/gradle/dependency-locks/testRuntimeClasspath.lockfile b/gradle/util/gradle/dependency-locks/testRuntimeClasspath.lockfile index fbbe9e934..a90ec8399 100644 --- a/gradle/util/gradle/dependency-locks/testRuntimeClasspath.lockfile +++ b/gradle/util/gradle/dependency-locks/testRuntimeClasspath.lockfile @@ -108,8 +108,9 @@ com.googlecode.java-diff-utils:diffutils:1.3.0 com.googlecode.json-simple:json-simple:1.1.1 com.ibm.icu:icu4j:57.1 com.jcraft:jsch:0.1.53 +com.squareup.okhttp3:okhttp:3.11.0 com.squareup.okhttp:okhttp:2.5.0 -com.squareup.okio:okio:1.6.0 +com.squareup.okio:okio:1.14.0 com.sun.istack:istack-commons-runtime:3.0.5 com.sun.xml.fastinfoset:FastInfoset:1.2.13 com.thoughtworks.paranamer:paranamer:2.7 @@ -154,6 +155,7 @@ javax.xml.bind:jaxb-api:2.3.0 jline:jline:1.0 joda-time:joda-time:2.9.2 junit:junit:4.12 +net.bytebuddy:byte-buddy:1.8.15 org.apache.avro:avro:1.8.2 org.apache.beam:beam-runners-direct-java:2.2.0 org.apache.beam:beam-runners-google-cloud-dataflow-java:2.1.0 @@ -163,6 +165,9 @@ org.apache.beam:beam-sdks-java-extensions-google-cloud-platform-core:2.2.0 org.apache.beam:beam-sdks-java-extensions-protobuf:2.2.0 org.apache.beam:beam-sdks-java-io-google-cloud-platform:2.2.0 org.apache.commons:commons-compress:1.8.1 +org.apache.commons:commons-exec:1.3 +org.apache.commons:commons-lang3:3.8.1 +org.apache.commons:commons-text:1.6 org.apache.ftpserver:ftplet-api:1.0.6 org.apache.ftpserver:ftpserver-core:1.0.6 org.apache.httpcomponents:httpclient:4.5.5 @@ -201,6 +206,16 @@ org.ow2.asm:asm-commons:6.0 org.ow2.asm:asm-tree:6.0 org.ow2.asm:asm-util:6.0 org.ow2.asm:asm:6.0 +org.seleniumhq.selenium:selenium-api:3.141.59 +org.seleniumhq.selenium:selenium-chrome-driver:3.141.59 +org.seleniumhq.selenium:selenium-edge-driver:3.141.59 +org.seleniumhq.selenium:selenium-firefox-driver:3.141.59 +org.seleniumhq.selenium:selenium-ie-driver:3.141.59 +org.seleniumhq.selenium:selenium-java:3.141.59 +org.seleniumhq.selenium:selenium-opera-driver:3.141.59 +org.seleniumhq.selenium:selenium-remote-driver:3.141.59 +org.seleniumhq.selenium:selenium-safari-driver:3.141.59 +org.seleniumhq.selenium:selenium-support:3.141.59 org.slf4j:slf4j-api:1.7.25 org.threeten:threetenbp:1.3.3 org.tukaani:xz:1.5 diff --git a/javatests/google/registry/server/RegistryTestServer.java b/javatests/google/registry/server/RegistryTestServer.java index b7ebe7c27..610701666 100644 --- a/javatests/google/registry/server/RegistryTestServer.java +++ b/javatests/google/registry/server/RegistryTestServer.java @@ -26,31 +26,27 @@ import google.registry.module.frontend.FrontendServlet; import java.net.URL; import java.nio.file.Path; import java.nio.file.Paths; + +import java.util.Optional; import javax.servlet.Filter; /** Lightweight HTTP server for testing the Nomulus Admin and Registrar consoles. */ public final class RegistryTestServer { + // In most cases, the current working dir is ${projectRoot}/gradle/${subproject} + private static final String PROJECT_ROOT = + Optional.ofNullable(System.getProperty("test.projectRoot")).orElse("../../"); + private static final String RESOURCES_DIR = + Optional.ofNullable(System.getProperty("test.resourcesDir")).orElse("build/resources/main"); + public static final ImmutableMap RUNFILES = new ImmutableMap.Builder() - .put( - "/index.html", - Paths.get( - "../domain_registry/java/google/registry/ui/html/index.html")) - .put( - "/error.html", - Paths.get( - "../domain_registry/java/google/registry/ui/html/error.html")) - .put( - "/assets/js/*", - Paths.get("../domain_registry/java/google/registry/ui")) - .put( - "/assets/css/*", - Paths.get("../domain_registry/java/google/registry/ui/css")) - .put("/assets/sources/*", Paths.get("..")) - .put( - "/assets/*", - Paths.get("../domain_registry/java/google/registry/ui/assets")) + .put("/index.html", Paths.get(PROJECT_ROOT, "/java/google/registry/ui/html/index.html")) + .put("/error.html", Paths.get(PROJECT_ROOT, "/java/google/registry/ui/html/error.html")) + .put("/assets/js/*", Paths.get(RESOURCES_DIR, "/google/registry/ui")) + .put("/assets/css/*", Paths.get(RESOURCES_DIR, "/google/registry/ui/css")) + .put("/assets/sources/*", Paths.get(PROJECT_ROOT)) + .put("/assets/*", Paths.get(PROJECT_ROOT, "/java/google/registry/ui/assets")) .build(); private static final ImmutableList ROUTES = diff --git a/javatests/google/registry/webdriver/ChromeWebDriverPlusScreenDiffer.java b/javatests/google/registry/webdriver/ChromeWebDriverPlusScreenDiffer.java new file mode 100644 index 000000000..4e6b65415 --- /dev/null +++ b/javatests/google/registry/webdriver/ChromeWebDriverPlusScreenDiffer.java @@ -0,0 +1,71 @@ +// 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 java.io.IOException; +import java.io.UncheckedIOException; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.chrome.ChromeDriver; +import org.openqa.selenium.chrome.ChromeDriverService; +import org.openqa.selenium.chrome.ChromeOptions; + +/** Implementation of {@link WebDriverPlusScreenDiffer} that uses {@link ChromeDriver}. */ +class ChromeWebDriverPlusScreenDiffer implements WebDriverPlusScreenDiffer { + + private static final ChromeDriverService chromeDriverService = createChromeDriverService(); + private final WebDriver webDriver; + + public ChromeWebDriverPlusScreenDiffer() { + ChromeOptions chromeOptions = new ChromeOptions(); + chromeOptions.setHeadless(true); + webDriver = new ChromeDriver(chromeDriverService, chromeOptions); + } + + private static ChromeDriverService createChromeDriverService() { + ChromeDriverService chromeDriverService = + new ChromeDriverService.Builder().usingAnyFreePort().build(); + try { + chromeDriverService.start(); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + Runtime.getRuntime().addShutdownHook(new Thread(chromeDriverService::stop)); + return chromeDriverService; + } + + @Override + public WebDriver getWebDriver() { + return webDriver; + } + + @Override + public void diffElement(String imageKey, WebElement element) { + // TODO(b/122650673): Add implementation for screenshots comparison. It is no-op + // right now to prevent the test failure. + } + + @Override + public void diffPage(String imageKey) { + // TODO(b/122650673): Add implementation for screenshots comparison. It is no-op + // right now to prevent the test failure. + } + + @Override + public void verifyAndQuit() { + // TODO(b/122650673): Add implementation for screenshots comparison. It is no-op + // right now to prevent the test failure. + } +} diff --git a/javatests/google/registry/webdriver/OteSetupConsoleScreenshotTest.java b/javatests/google/registry/webdriver/OteSetupConsoleScreenshotTest.java new file mode 100644 index 000000000..d192fd65a --- /dev/null +++ b/javatests/google/registry/webdriver/OteSetupConsoleScreenshotTest.java @@ -0,0 +1,83 @@ +// Copyright 2018 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 google.registry.server.Fixture.BASIC; +import static google.registry.server.Route.route; + +import com.googlecode.objectify.ObjectifyFilter; +import google.registry.model.ofy.OfyFilter; +import google.registry.module.frontend.FrontendServlet; +import google.registry.server.RegistryTestServer; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; +import org.openqa.selenium.By; +import org.openqa.selenium.Dimension; + +/** Registrar Console Screenshot Differ tests. */ +@RunWith(JUnit4.class) +public class OteSetupConsoleScreenshotTest { + + @Rule + public final TestServerRule server = + new TestServerRule.Builder() + .setRunfiles(RegistryTestServer.RUNFILES) + .setRoutes(route("/registrar-ote-setup", FrontendServlet.class)) + .setFilters(ObjectifyFilter.class, OfyFilter.class) + .setFixtures(BASIC) + .setEmail("Marla.Singer@google.com") + .build(); + + @Rule public final WebDriverRule driver = new WebDriverRule(); + + @Test + public void get_owner_fails() throws Throwable { + driver.manage().window().setSize(new Dimension(1200, 2000)); + driver.get(server.getUrl("/registrar-ote-setup")); + driver.waitForElement(By.tagName("h1")); + driver.diffPage("unauthorized"); + } + + @Test + public void get_admin_succeeds() throws Throwable { + server.setIsAdmin(true); + driver.manage().window().setSize(new Dimension(1200, 2000)); + driver.get(server.getUrl("/registrar-ote-setup")); + driver.waitForElement(By.tagName("h1")); + driver.diffPage("formEmpty"); + driver.findElement(By.id("clientId")).sendKeys("acmereg"); + driver.findElement(By.id("email")).sendKeys("acmereg@registry.example"); + driver.findElement(By.id("password")).sendKeys("StRoNgPaSsWoRd"); + driver.diffPage("formFilled"); + driver.findElement(By.id("submit-button")).click(); + driver.waitForElement(By.tagName("h1")); + driver.diffPage("oteResult"); + } + + @Test + public void get_admin_fails_badEmail() throws Throwable { + server.setIsAdmin(true); + driver.manage().window().setSize(new Dimension(1200, 2000)); + driver.get(server.getUrl("/registrar-ote-setup")); + driver.waitForElement(By.tagName("h1")); + driver.findElement(By.id("clientId")).sendKeys("acmereg"); + driver.findElement(By.id("email")).sendKeys("bad email"); + driver.findElement(By.id("submit-button")).click(); + driver.waitForElement(By.tagName("h1")); + driver.diffPage("oteResultFailed"); + } +} diff --git a/javatests/google/registry/webdriver/RegistrarConsoleScreenshotTest.java b/javatests/google/registry/webdriver/RegistrarConsoleScreenshotTest.java new file mode 100644 index 000000000..dccbcaafc --- /dev/null +++ b/javatests/google/registry/webdriver/RegistrarConsoleScreenshotTest.java @@ -0,0 +1,373 @@ +// Copyright 2017 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 google.registry.server.Fixture.BASIC; +import static google.registry.server.Route.route; +import static google.registry.testing.DatastoreHelper.loadRegistrar; +import static google.registry.testing.DatastoreHelper.persistResource; +import static google.registry.util.DateTimeUtils.START_OF_TIME; + +import com.google.common.collect.ImmutableMap; +import com.googlecode.objectify.ObjectifyFilter; +import google.registry.model.ofy.OfyFilter; +import google.registry.module.frontend.FrontendServlet; +import google.registry.server.RegistryTestServer; +import google.registry.testing.CertificateSamples; +import org.junit.Ignore; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; +import org.openqa.selenium.By; +import org.openqa.selenium.Dimension; + +/** Registrar Console Screenshot Differ tests. */ +@RunWith(JUnit4.class) +public class RegistrarConsoleScreenshotTest { + + @Rule + public final TestServerRule server = + new TestServerRule.Builder() + .setRunfiles(RegistryTestServer.RUNFILES) + .setRoutes( + route("/registrar", FrontendServlet.class), + route("/registrar-ote-status", FrontendServlet.class), + route("/registrar-settings", FrontendServlet.class), + route("/registrar-xhr", FrontendServlet.class)) + .setFilters(ObjectifyFilter.class, OfyFilter.class) + .setFixtures(BASIC) + .setEmail("Marla.Singer@google.com") + .build(); + + @Rule public final WebDriverRule driver = new WebDriverRule(); + + @Test + public void index_owner() throws Throwable { + driver.manage().window().setSize(new Dimension(1200, 2000)); + driver.get(server.getUrl("/registrar")); + driver.waitForElement(By.tagName("h1")); + driver.diffPage("page"); + } + + /** Admins have an extra "admin" tab. */ + @Test + public void index_adminAndOwner() throws Throwable { + server.setIsAdmin(true); + driver.manage().window().setSize(new Dimension(1200, 2000)); + driver.get(server.getUrl("/registrar")); + driver.waitForElement(By.tagName("h1")); + driver.diffPage("page"); + } + + /** Admins who aren't owners still have all the tabs. */ + @Test + public void index_admin() throws Throwable { + server.setIsAdmin(true); + driver.manage().window().setSize(new Dimension(1200, 2000)); + // To make sure we're only ADMIN (and not also "OWNER"), we switch to the NewRegistrar we + // aren't in the contacts of + driver.get(server.getUrl("/registrar?clientId=NewRegistrar")); + driver.waitForElement(By.tagName("h1")); + driver.diffPage("page"); + } + + @Test + public void contactUs() throws Throwable { + driver.get(server.getUrl("/registrar#contact-us")); + driver.waitForElement(By.tagName("h1")); + driver.diffPage("page"); + } + + @Test + public void settingsContact() throws Throwable { + driver.get(server.getUrl("/registrar#contact-settings")); + Thread.sleep(1000); + driver.waitForElement(By.tagName("h1")); + driver.diffPage("page"); + } + + /** Admins shouldn't have the "add" button */ + @Test + public void settingsContact_asAdmin() throws Throwable { + server.setIsAdmin(true); + driver.get(server.getUrl("/registrar?clientId=NewRegistrar#contact-settings")); + Thread.sleep(1000); + driver.waitForElement(By.tagName("h1")); + driver.diffPage("page"); + } + + @Test + public void settingsContactItem() throws Throwable { + driver.get(server.getUrl("/registrar#contact-settings/johndoe@theregistrar.com")); + Thread.sleep(1000); + driver.waitForElement(By.tagName("h1")); + driver.diffPage("page"); + } + + /** Admins shouldn't have the "edit" button */ + @Test + public void settingsContactItem_asAdmin() throws Throwable { + server.setIsAdmin(true); + driver.get(server.getUrl("/registrar?clientId=NewRegistrar#contact-settings/janedoe@theregistrar.com")); + Thread.sleep(1000); + driver.waitForElement(By.tagName("h1")); + driver.diffPage("page"); + } + + @Test + public void settingsContactEdit() throws Throwable { + driver.manage().window().setSize(new Dimension(1050, 2000)); + driver.get(server.getUrl("/registrar#contact-settings/johndoe@theregistrar.com")); + Thread.sleep(1000); + driver.waitForElement(By.tagName("h1")); + driver.waitForElement(By.id("reg-app-btn-edit")).click(); + driver.diffPage("page"); + } + + @Test + public void settingsAdmin_whenAdmin() throws Throwable { + server.setIsAdmin(true); + driver.manage().window().setSize(new Dimension(1050, 2000)); + // To make sure we're only ADMIN (and not also "OWNER"), we switch to the NewRegistrar we + // aren't in the contacts of + driver.get(server.getUrl("/registrar?clientId=NewRegistrar#admin-settings")); + driver.waitForElement(By.tagName("h1")); + driver.diffPage("view"); + driver.waitForElement(By.id("reg-app-btn-edit")).click(); + driver.waitForElement(By.tagName("h1")); + driver.diffPage("edit"); + } + + /** + * Makes sure the user can't "manually" enter the admin-settings. + * + *

Users don't have the "admin setting" tab (see the {@link #index_owner()} test). However, we + * also want to make sure that if a user enter's the URL fragment manually they don't get the + * admin page. + * + *

Note that failure here is a UI issue only and not a security issue, since any "admin" change + * a user tries to do is validated on the backend and fails for non-admins. + */ + @Test + public void settingsAdmin_whenNotAdmin_showsHome() throws Throwable { + driver.manage().window().setSize(new Dimension(1050, 2000)); + driver.get(server.getUrl("/registrar#admin-settings")); + driver.waitForElement(By.tagName("h1")); + driver.diffPage("view"); + } + + @Test + public void getOteStatus_noButtonWhenReal() throws Exception { + server.setIsAdmin(true); + driver.get(server.getUrl("/registrar#admin-settings")); + driver.waitForElement(By.tagName("h1")); + driver.diffPage("result"); + } + + @Test + public void getOteStatus_notCompleted() throws Exception { + server.setIsAdmin(true); + driver.get(server.getUrl("/registrar?clientId=oteunfinished-1#admin-settings")); + driver.findElement(By.id("btn-ote-status")).click(); + driver.findElement(By.id("ote-results-table")).click(); + // the 'hover' styling takes a bit to go away--sleep so we don't flake + Thread.sleep(250); + driver.diffPage("result"); + } + + @Test + public void getOteStatus_completed() throws Exception { + server.setIsAdmin(true); + driver.get(server.getUrl("/registrar?clientId=otefinished-1#admin-settings")); + driver.waitForElement(By.id("btn-ote-status")); + driver.diffPage("before_click"); + driver.findElement(By.id("btn-ote-status")).click(); + driver.findElement(By.id("ote-results-table")).click(); + // the 'hover' styling takes a bit to go away--sleep so we don't flake + Thread.sleep(250); + driver.diffPage("result"); + } + + @Test + public void settingsSecurity() throws Throwable { + driver.manage().window().setSize(new Dimension(1050, 2000)); + driver.get(server.getUrl("/registrar#security-settings")); + driver.waitForElement(By.tagName("h1")); + driver.diffPage("view"); + driver.waitForElement(By.id("reg-app-btn-edit")).click(); + driver.waitForElement(By.tagName("h1")); + driver.diffPage("edit"); + } + + /** Admins shouldn't have the "edit" button */ + @Test + public void settingsSecurity_asAdmin() throws Throwable { + server.setIsAdmin(true); + driver.manage().window().setSize(new Dimension(1050, 2000)); + driver.get(server.getUrl("/registrar?clientId=NewRegistrar#security-settings")); + driver.waitForElement(By.tagName("h1")); + driver.diffPage("view"); + } + + @Test + public void settingsSecurityWithCerts() throws Throwable { + server.runInAppEngineEnvironment( + () -> { + persistResource( + loadRegistrar("TheRegistrar") + .asBuilder() + .setClientCertificate(CertificateSamples.SAMPLE_CERT, START_OF_TIME) + .setFailoverClientCertificate(CertificateSamples.SAMPLE_CERT2, START_OF_TIME) + .build()); + return null; + }); + driver.manage().window().setSize(new Dimension(1050, 2000)); + driver.get(server.getUrl("/registrar#security-settings")); + driver.waitForElement(By.tagName("h1")); + driver.diffPage("view"); + driver.waitForElement(By.id("reg-app-btn-edit")).click(); + driver.waitForElement(By.tagName("h1")); + driver.diffPage("edit"); + } + + @Test + public void settingsSecurityWithHashOnly() throws Throwable { + server.runInAppEngineEnvironment( + () -> { + persistResource( + loadRegistrar("TheRegistrar") + .asBuilder() + .setClientCertificateHash(CertificateSamples.SAMPLE_CERT_HASH) + .build()); + return null; + }); + driver.manage().window().setSize(new Dimension(1050, 2000)); + driver.get(server.getUrl("/registrar#security-settings")); + driver.waitForElement(By.tagName("h1")); + driver.diffPage("view"); + driver.waitForElement(By.id("reg-app-btn-edit")).click(); + driver.waitForElement(By.tagName("h1")); + driver.diffPage("edit"); + } + + @Test + public void settingsWhois() throws Throwable { + driver.get(server.getUrl("/registrar#whois-settings")); + driver.waitForElement(By.tagName("h1")); + driver.diffPage("page"); + } + + @Test + public void settingsWhoisEdit() throws Throwable { + driver.manage().window().setSize(new Dimension(1050, 2000)); + driver.get(server.getUrl("/registrar#whois-settings")); + driver.waitForElement(By.id("reg-app-btn-edit")).click(); + Thread.sleep(1000); + driver.diffPage("page"); + } + + @Test + public void settingsWhoisEditError() throws Throwable { + driver.manage().window().setSize(new Dimension(1050, 2000)); + driver.get(server.getUrl("/registrar#whois-settings")); + driver.waitForElement(By.id("reg-app-btn-edit")).click(); + driver.setFormFieldsById(ImmutableMap.of("faxNumber", "cat")); + driver.waitForElement(By.id("reg-app-btn-save")).click(); + Thread.sleep(1000); + driver.diffPage("page"); + } + + // EPP pages aren't being included in launch, so temporarily disable the following tests. + + @Test + public void domainCreate() throws Throwable { + // TODO(b/17675279): Change labels to unicode. + driver.get(server.getUrl("/registrar#domain")); + driver.waitForElement(By.tagName("h1")); + driver.diffPage("page"); + } + + @Test + @Ignore("TODO(b/26984251): Unflake nameserver ordering.") + public void domainView() throws Throwable { + driver.get(server.getUrl("/registrar#domain/love.xn--q9jyb4c")); + driver.waitForElement(By.tagName("h1")); + driver.diffPage("page"); + } + + @Test + @Ignore("TODO(b/26984251): Unflake nameserver ordering.") + public void domainEdit() throws Throwable { + driver.get(server.getUrl("/registrar#domain/love.xn--q9jyb4c")); + driver.waitForElement(By.id("reg-app-btn-edit")).click(); + Thread.sleep(1000); + driver.diffPage("page"); + } + + @Test + public void contactCreate() throws Throwable { + driver.get(server.getUrl("/registrar#contact")); + driver.waitForElement(By.tagName("h1")); + driver.diffPage("page"); + } + + @Test + public void contactView() throws Throwable { + driver.get(server.getUrl("/registrar#contact/google")); + driver.waitForElement(By.tagName("h1")); + driver.diffPage("page"); + } + + @Test + public void contactEdit() throws Throwable { + driver.get(server.getUrl("/registrar#contact/google")); + driver.waitForElement(By.id("reg-app-btn-edit")).click(); + Thread.sleep(1000); + driver.diffPage("page"); + } + + @Test + public void hostCreate() throws Throwable { + driver.get(server.getUrl("/registrar#host")); + driver.waitForElement(By.tagName("h1")); + driver.diffPage("page"); + } + + @Test + public void hostView() throws Throwable { + driver.get(server.getUrl("/registrar#host/ns1.love.xn--q9jyb4c")); + driver.waitForElement(By.tagName("h1")); + driver.diffPage("page"); + } + + @Test + public void hostEdit() throws Throwable { + driver.get(server.getUrl("/registrar#host/ns1.love.xn--q9jyb4c")); + driver.waitForElement(By.id("reg-app-btn-edit")).click(); + Thread.sleep(1000); + driver.diffPage("page"); + } + + @Test + public void indexPage_smallScrolledDown() throws Throwable { + driver.manage().window().setSize(new Dimension(400, 300)); + driver.get(server.getUrl("/registrar")); + driver.waitForElement(By.tagName("h1")); + driver.executeScript("document.getElementById('reg-content-and-footer').scrollTop = 200"); + Thread.sleep(500); + driver.diffPage("page"); + } +} diff --git a/javatests/google/registry/webdriver/RegistrarConsoleWebTest.java b/javatests/google/registry/webdriver/RegistrarConsoleWebTest.java new file mode 100644 index 000000000..3146607a8 --- /dev/null +++ b/javatests/google/registry/webdriver/RegistrarConsoleWebTest.java @@ -0,0 +1,252 @@ +// Copyright 2017 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 static google.registry.server.Route.route; +import static google.registry.testing.DatastoreHelper.createTld; +import static google.registry.testing.DatastoreHelper.loadRegistrar; +import static google.registry.testing.DatastoreHelper.persistActiveDomain; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.googlecode.objectify.ObjectifyFilter; +import google.registry.model.ofy.OfyFilter; +import google.registry.model.registrar.Registrar; +import google.registry.model.registrar.RegistrarAddress; +import google.registry.model.registrar.RegistrarContact; +import google.registry.module.frontend.FrontendServlet; +import google.registry.server.RegistryTestServer; +import google.registry.testing.AppEngineRule; +import google.registry.ui.server.registrar.ConsoleUiAction; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.Timeout; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; +import org.openqa.selenium.By; + +/** WebDriver tests for Registrar Console UI. */ +@RunWith(JUnit4.class) +public class RegistrarConsoleWebTest { + + @Rule + public final AppEngineRule appEngine = AppEngineRule.builder() + .withDatastore() + .withLocalModules() + .withTaskQueue() + .build(); + + @Rule + public final TestServerRule server = + new TestServerRule.Builder() + .setRunfiles(RegistryTestServer.RUNFILES) + .setRoutes( + route("/registrar-xhr", FrontendServlet.class), + route("/registrar", FrontendServlet.class), + route("/registrar-settings", FrontendServlet.class)) + .setFilters(ObjectifyFilter.class, OfyFilter.class) + .setFixtures(BASIC) + .setEmail("Marla.Singer@google.com") + .build(); + + @Rule public final WebDriverRule driver = new WebDriverRule(); + + + @Rule public final Timeout deathClock = new Timeout(60000); + + /** Checks the identified element has the given text content. */ + void assertEltText(String eltId, String eltValue) { + assertThat(driver.findElement(By.id(eltId)).getText()).isEqualTo(eltValue); + } + + /** Checks that an element is visible. */ + void assertEltVisible(String eltId) throws Throwable { + assertThat(driver.waitForElement(By.id(eltId)).isDisplayed()).isTrue(); + } + + /** Checks that an element is invisible. */ + void assertEltInvisible(String eltId) throws Throwable { + assertThat(driver.waitForElement(By.id(eltId)).isDisplayed()).isFalse(); + } + + @Test + public void testEditButtonsVisibility_owner() throws Throwable { + driver.get(server.getUrl("/registrar#whois-settings")); + assertEltVisible("reg-app-btns-edit"); + assertEltInvisible("reg-app-btn-add"); + + driver.get(server.getUrl("/registrar#security-settings")); + assertEltVisible("reg-app-btns-edit"); + assertEltInvisible("reg-app-btn-add"); + + driver.get(server.getUrl("/registrar#contact-settings")); + assertEltInvisible("reg-app-btns-edit"); + assertEltVisible("reg-app-btn-add"); + + driver.get(server.getUrl("/registrar#resources")); + assertEltVisible("reg-app-btns-edit"); + assertEltInvisible("reg-app-btn-add"); + } + + @Test + public void testEditButtonsVisibility_adminAndOwner() throws Throwable { + server.setIsAdmin(true); + driver.get(server.getUrl("/registrar#whois-settings")); + assertEltVisible("reg-app-btns-edit"); + assertEltInvisible("reg-app-btn-add"); + + driver.get(server.getUrl("/registrar#security-settings")); + assertEltVisible("reg-app-btns-edit"); + assertEltInvisible("reg-app-btn-add"); + + driver.get(server.getUrl("/registrar#contact-settings")); + assertEltInvisible("reg-app-btns-edit"); + assertEltVisible("reg-app-btn-add"); + + driver.get(server.getUrl("/registrar#admin-settings")); + assertEltVisible("reg-app-btns-edit"); + assertEltInvisible("reg-app-btn-add"); + + driver.get(server.getUrl("/registrar#resources")); + assertEltVisible("reg-app-btns-edit"); + assertEltInvisible("reg-app-btn-add"); + } + + @Test + public void testEditButtonsVisibility_adminOnly() throws Throwable { + server.setIsAdmin(true); + // To make sure we're only ADMIN (and not also "OWNER"), we switch to the NewRegistrar we + // aren't in the contacts of + driver.get(server.getUrl("/registrar?clientId=NewRegistrar#whois-settings")); + assertEltInvisible("reg-app-btns-edit"); + assertEltInvisible("reg-app-btn-add"); + + driver.get(server.getUrl("/registrar?clientId=NewRegistrar#security-settings")); + assertEltInvisible("reg-app-btns-edit"); + assertEltInvisible("reg-app-btn-add"); + + driver.get(server.getUrl("/registrar?clientId=NewRegistrar#contact-settings")); + assertEltInvisible("reg-app-btns-edit"); + assertEltInvisible("reg-app-btn-add"); + + driver.get(server.getUrl("/registrar?clientId=NewRegistrar#admin-settings")); + assertEltVisible("reg-app-btns-edit"); + assertEltInvisible("reg-app-btn-add"); + + driver.get(server.getUrl("/registrar?clientId=NewRegistrar#resources")); + assertEltInvisible("reg-app-btns-edit"); + assertEltInvisible("reg-app-btn-add"); + } + + @Test + public void testWhoisSettingsEdit() throws Throwable { + driver.get(server.getUrl("/registrar#whois-settings")); + driver.waitForElement(By.id("reg-app-btn-edit")).click(); + driver.setFormFieldsById(new ImmutableMap.Builder() + .put("emailAddress", "test1@example.com") + .put("clientIdentifier", "ignored") + .put("whoisServer", "foo.bar.baz") + .put("url", "blah.blar") + .put("phoneNumber", "+1.2125650000") + .put("faxNumber", "+1.2125650001") + .put("localizedAddress.street[0]", "Bőulevard őf") + .put("localizedAddress.street[1]", "Brőken Dreams") + .put("localizedAddress.street[2]", "") + .put("localizedAddress.city", "New York") + .put("localizedAddress.state", "NY") + .put("localizedAddress.zip", "10011") + .put("localizedAddress.countryCode", "US") + .build()); + driver.findElement(By.id("reg-app-btn-save")).click(); + Thread.sleep(1000); + Registrar registrar = server.runInAppEngineEnvironment(() -> loadRegistrar("TheRegistrar")); + assertThat(registrar.getEmailAddress()).isEqualTo("test1@example.com"); + assertThat(registrar.getClientId()).isEqualTo("TheRegistrar"); + assertThat(registrar.getWhoisServer()).isEqualTo("foo.bar.baz"); + assertThat(registrar.getUrl()).isEqualTo("blah.blar"); + assertThat(registrar.getPhoneNumber()).isEqualTo("+1.2125650000"); + assertThat(registrar.getFaxNumber()).isEqualTo("+1.2125650001"); + RegistrarAddress address = registrar.getLocalizedAddress(); + assertThat(address.getStreet()).containsExactly("Bőulevard őf", "Brőken Dreams"); + assertThat(address.getCity()).isEqualTo("New York"); + assertThat(address.getState()).isEqualTo("NY"); + assertThat(address.getZip()).isEqualTo("10011"); + assertThat(address.getCountryCode()).isEqualTo("US"); + } + + @Test + public void testContactSettingsView() throws Throwable { + driver.get(server.getUrl("/registrar#contact-settings")); + driver.waitForElement(By.id("reg-app-btn-add")); + ImmutableList contacts = + server.runInAppEngineEnvironment( + () -> loadRegistrar("TheRegistrar").getContacts().asList()); + assertEltText("contacts[0].name", contacts.get(0).getName()); + assertEltText("contacts[0].emailAddress", contacts.get(0).getEmailAddress()); + assertEltText("contacts[0].phoneNumber", contacts.get(0).getPhoneNumber()); + } + + @Test + public void testSecuritySettingsView() throws Throwable { + driver.get(server.getUrl("/registrar#security-settings")); + driver.waitForElement(By.id("reg-app-btn-edit")); + Registrar registrar = server.runInAppEngineEnvironment(() -> loadRegistrar("TheRegistrar")); + assertThat(driver.findElement(By.id("phonePasscode")) + .getAttribute("value")) + .isEqualTo(registrar.getPhonePasscode()); + } + + @Test + public void testHostCreate_hostIsAnSld_eppErrorShowsInButterBar() throws Throwable { + driver.get(server.getUrl("/registrar#host")); + driver.waitForElement(By.id("domain-host-addr-add-button")).click(); + driver.setFormFieldsById(ImmutableMap.of( + "host:name", "empire.vampyre", + "host:addr[0].value", "1.2.3.4")); + driver.findElement(By.id("reg-app-btn-save")).click(); + Thread.sleep(1000); // TODO(b/26129174): Change butterbar code to add/remove dynamically. + assertThat(getButterBarText()) + .isEqualTo("Host names must be at least two levels below the registry suffix"); + } + + @Test + public void testHostCreate() throws Throwable { + server.runInAppEngineEnvironment( + () -> { + createTld("vampyre"); + persistActiveDomain("empire.vampyre"); + return null; + }); + driver.get(server.getUrl("/registrar#host")); + driver.waitForElement(By.id("domain-host-addr-add-button")).click(); + driver.setFormFieldsById(ImmutableMap.of( + "host:name", "the.empire.vampyre", + "host:addr[0].value", "1.2.3.4")); + driver.findElement(By.id("reg-app-btn-save")).click(); + Thread.sleep(1000); // TODO(b/26129174): Change butterbar code to add/remove dynamically. + assertThat(getButterBarText()).isEqualTo("Saved."); + } + + private String getButterBarText() { + return (String) driver.executeScript( + String.format("return document.querySelector('.%s').innerText", css("kd-butterbar-text"))); + } + + private static String css(String name) { + return ConsoleUiAction.CSS_RENAMING_MAP_SUPPLIER.get().get(name); + } +} diff --git a/javatests/google/registry/webdriver/RegistrarCreateConsoleScreenshotTest.java b/javatests/google/registry/webdriver/RegistrarCreateConsoleScreenshotTest.java new file mode 100644 index 000000000..096e7d999 --- /dev/null +++ b/javatests/google/registry/webdriver/RegistrarCreateConsoleScreenshotTest.java @@ -0,0 +1,108 @@ +// Copyright 2018 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 google.registry.server.Fixture.BASIC; +import static google.registry.server.Route.route; + +import com.googlecode.objectify.ObjectifyFilter; +import google.registry.model.ofy.OfyFilter; +import google.registry.module.frontend.FrontendServlet; +import google.registry.server.RegistryTestServer; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; +import org.openqa.selenium.By; +import org.openqa.selenium.Dimension; + +/** Registrar Console Screenshot Differ tests. */ +@RunWith(JUnit4.class) +public class RegistrarCreateConsoleScreenshotTest { + + @Rule + public final TestServerRule server = + new TestServerRule.Builder() + .setRunfiles(RegistryTestServer.RUNFILES) + .setRoutes(route("/registrar-create", FrontendServlet.class)) + .setFilters(ObjectifyFilter.class, OfyFilter.class) + .setFixtures(BASIC) + .setEmail("Marla.Singer@google.com") + .build(); + + @Rule public final WebDriverRule driver = new WebDriverRule(); + + @Test + public void get_owner_fails() throws Throwable { + driver.manage().window().setSize(new Dimension(1200, 2000)); + driver.get(server.getUrl("/registrar-create")); + driver.waitForElement(By.tagName("h1")); + driver.diffPage("unauthorized"); + } + + @Test + public void get_admin_succeeds() throws Throwable { + server.setIsAdmin(true); + driver.manage().window().setSize(new Dimension(1200, 2000)); + driver.get(server.getUrl("/registrar-create")); + driver.waitForElement(By.tagName("h1")); + driver.diffPage("formEmpty"); + driver.findElement(By.id("clientId")).sendKeys("my-name"); + driver.findElement(By.id("name")).sendKeys("registrar name"); + driver + .findElement(By.id("billingAccount")) + .sendKeys("" + + "USD=12345678-abcd-1234-5678-cba987654321\n" + + "JPY=aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"); + driver.findElement(By.id("driveId")).sendKeys("drive-id"); + driver.findElement(By.id("ianaId")).sendKeys("15263"); + driver.findElement(By.id("referralEmail")).sendKeys("email@icann.example"); + driver.findElement(By.id("email")).sendKeys("my-name@registry.example"); + driver.findElement(By.id("street1")).sendKeys("123 Street st."); + driver.findElement(By.id("city")).sendKeys("Citysville"); + driver.findElement(By.id("countryCode")).sendKeys("fr"); + driver.findElement(By.id("password")).sendKeys("StRoNgPaSsWoRd"); + driver.findElement(By.id("passcode")).sendKeys("01234"); + driver.diffPage("formFilled"); + driver.findElement(By.id("submit-button")).click(); + driver.waitForElement(By.tagName("h1")); + driver.diffPage("createResult"); + } + + @Test + public void get_admin_fails_badEmail() throws Throwable { + server.setIsAdmin(true); + driver.manage().window().setSize(new Dimension(1200, 2000)); + driver.get(server.getUrl("/registrar-create")); + driver.waitForElement(By.tagName("h1")); + driver.findElement(By.id("clientId")).sendKeys("my-name"); + driver.findElement(By.id("name")).sendKeys("registrar name"); + driver + .findElement(By.id("billingAccount")) + .sendKeys("" + + "USD=12345678-abcd-1234-5678-cba987654321\n" + + "JPY=aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"); + driver.findElement(By.id("driveId")).sendKeys("drive-id"); + driver.findElement(By.id("ianaId")).sendKeys("15263"); + driver.findElement(By.id("referralEmail")).sendKeys("email@icann.example"); + driver.findElement(By.id("email")).sendKeys("bad email"); + driver.findElement(By.id("street1")).sendKeys("123 Street st."); + driver.findElement(By.id("city")).sendKeys("Citysville"); + driver.findElement(By.id("countryCode")).sendKeys("fr"); + driver.findElement(By.id("submit-button")).click(); + driver.waitForElement(By.tagName("h1")); + driver.diffPage("createResultFailed"); + } +} diff --git a/javatests/google/registry/webdriver/TestServerRule.java b/javatests/google/registry/webdriver/TestServerRule.java new file mode 100644 index 000000000..cb021381f --- /dev/null +++ b/javatests/google/registry/webdriver/TestServerRule.java @@ -0,0 +1,247 @@ +// Copyright 2017 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.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static google.registry.testing.AppEngineRule.THE_REGISTRAR_GAE_USER_ID; +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.request.auth.AuthenticatedRegistrarAccessor; +import google.registry.server.Fixture; +import google.registry.server.Route; +import google.registry.server.TestServer; +import google.registry.testing.AppEngineRule; +import google.registry.testing.UserInfo; +import java.net.URL; +import java.nio.file.Path; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.Callable; +import java.util.concurrent.FutureTask; +import java.util.concurrent.LinkedBlockingDeque; +import javax.servlet.Filter; +import org.junit.rules.ExternalResource; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; + +/** + * JUnit Rule that sets up and tears down {@link TestServer}. + * + *

Warning: App Engine testing environments are thread local. This rule will spawn that + * testing environment in a separate thread from your unit tests. Therefore any modifications you + * need to make to that testing environment (e.g. Datastore interactions) must be done through the + * {@link #runInAppEngineEnvironment(Callable)} method. + */ +public final class TestServerRule extends ExternalResource { + + private final ImmutableList fixtures; + private final AppEngineRule appEngineRule; + private final BlockingQueue> jobs = new LinkedBlockingDeque<>(); + private final TestServer testServer; + + private Thread serverThread; + + private TestServerRule( + ImmutableMap runfiles, + ImmutableList routes, + ImmutableList> filters, + ImmutableList fixtures, + String email) { + this.fixtures = fixtures; + // We create an GAE-Admin user, and then use AuthenticatedRegistrarAccessor.bypassAdminCheck to + // choose whether the user is an admin or not. + this.appEngineRule = AppEngineRule.builder() + .withDatastore() + .withLocalModules() + .withUrlFetch() + .withTaskQueue() + .withUserService(UserInfo.createAdmin(email, THE_REGISTRAR_GAE_USER_ID)) + .build(); + this.testServer = new TestServer( + HostAndPort.fromParts("localhost", pickUnusedPort()), + runfiles, + routes, + filters); + } + + @Override + protected void before() throws InterruptedException { + setIsAdmin(false); + serverThread = new Thread(new Server()); + synchronized (testServer) { + serverThread.start(); + testServer.wait(); + } + } + + @Override + protected void after() { + // Reset the global state AuthenticatedRegistrarAccessor.bypassAdminCheck + // to the default value so it doesn't interfere with other tests + AuthenticatedRegistrarAccessor.bypassAdminCheck = false; + serverThread.interrupt(); + try { + serverThread.join(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } finally { + serverThread = null; + jobs.clear(); + } + } + + /** + * Set the current user's Admin status. + * + *

This is sort of a hack because we can't actually change the user itself, nor that user's GAE + * roles. Instead we created a GAE-admin user in the constructor and we "bypass the admin check" + * if we want that user to not be an admin. + * + *

A better implementation would be to replace the AuthenticatedRegistrarAccessor - that way we + * can fully control the Roles the user has without relying on the implementation. But right now + * we don't have the ability to change injected values like that :/ + */ + public void setIsAdmin(boolean isAdmin) { + AuthenticatedRegistrarAccessor.bypassAdminCheck = !isAdmin; + } + + /** @see TestServer#getUrl(String) */ + public URL getUrl(String path) { + return testServer.getUrl(path); + } + + /** + * Runs arbitrary code inside server event loop thread. + * + *

You should use this method when you want to do things like change Datastore, because the + * App Engine testing environment is thread-local. + */ + public T runInAppEngineEnvironment(Callable callback) throws Throwable { + FutureTask job = new FutureTask<>(callback); + jobs.add(job); + testServer.ping(); + return job.get(); + } + + private final class Server extends Statement implements Runnable { + @Override + public void run() { + try { + appEngineRule + .apply(this, Description.EMPTY) + .evaluate(); + } catch (InterruptedException e) { + // This is what we expect to happen. + } catch (Throwable e) { + throw new RuntimeException(e); + } + } + + @Override + public void evaluate() throws InterruptedException { + for (Fixture fixture : fixtures) { + fixture.load(); + } + testServer.start(); + System.out.printf("TestServerRule is listening on: %s\n", testServer.getUrl("/")); + synchronized (testServer) { + testServer.notify(); + } + try { + while (true) { + testServer.process(); + flushJobs(); + } + } finally { + testServer.stop(); + } + } + + private void flushJobs() { + while (true) { + FutureTask job = jobs.poll(); + if (job != null) { + job.run(); + } else { + break; + } + } + } + } + + /** + * Builder for {@link TestServerRule}. + * + *

This builder has three required fields: {@link #setRunfiles}, {@link #setRoutes}, and {@link + * #setFilters}. + * + */ + public static final class Builder { + private ImmutableMap runfiles; + private ImmutableList routes; + ImmutableList> filters; + private ImmutableList fixtures = ImmutableList.of(); + private String email; + + /** Sets the directories containing the static files for {@link TestServer}. */ + public Builder setRunfiles(ImmutableMap runfiles) { + this.runfiles = runfiles; + 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; + } + + /** Sets the list of servlet {@link Filter} objects for {@link TestServer}. */ + @SafeVarargs + public final Builder setFilters(Class... filters) { + this.filters = ImmutableList.copyOf(filters); + return this; + } + + /** Sets an ordered list of Datastore fixtures that should be loaded on startup. */ + public Builder setFixtures(Fixture... fixtures) { + this.fixtures = ImmutableList.copyOf(fixtures); + return this; + } + + /** + * Sets information about the logged in user. + * + *

This unfortunately cannot be changed by test methods. + */ + public Builder setEmail(String email) { + this.email = email; + return this; + } + + /** Returns a new {@link TestServerRule} instance. */ + public TestServerRule build() { + return new TestServerRule( + checkNotNull(this.runfiles), + checkNotNull(this.routes), + checkNotNull(this.filters), + checkNotNull(this.fixtures), + checkNotNull(this.email)); + } + } +} diff --git a/javatests/google/registry/webdriver/WebDriverPlusScreenDiffer.java b/javatests/google/registry/webdriver/WebDriverPlusScreenDiffer.java new file mode 100644 index 000000000..0459393c3 --- /dev/null +++ b/javatests/google/registry/webdriver/WebDriverPlusScreenDiffer.java @@ -0,0 +1,58 @@ +// 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 org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; + +/** + * Interface to provide the implementation of {@link org.openqa.selenium.WebDriver} and APIs to + * compare screenshots for visual regression tests. + */ +interface WebDriverPlusScreenDiffer { + + /** Gets the implementation of {@link org.openqa.selenium.WebDriver}. */ + WebDriver getWebDriver(); + + /** + * Checks that the screenshot of the element matches the golden image by pixel comparison. {@link + * #verifyAndQuit()} needs to be invoked to actually trigger the comparison. + * + *

On mismatch, the test will continue until the end of the test (and then fail). This is so + * other screenshot matches can be executed in the same function - allowing you to approve / + * reject all at once. + * + * @param imageKey a unique name such that by prepending the calling class name and method name in + * the format of ClassName_MethodName_ will uniquely identify golden image. + * @param element the element on the page to be compared + */ + void diffElement(String imageKey, WebElement element); + + /** + * Checks that the screenshot matches the golden image by pixel comparison. {@link + * #verifyAndQuit()} needs to be invoked to actually trigger the comparison. + * + *

On mismatch, the test will continue until the end of the test (and then fail). This is so + * other screenshot matches can be executed in the same function - allowing you to approve / + * reject all at once. + * + * @param imageKey a unique name such that by prepending the calling class name and method name in + * the format of ClassName_MethodName_ will uniquely identify golden image. + */ + void diffPage(String imageKey); + + /** Asserts that all diffs up to this point have PASSED. */ + void verifyAndQuit(); +} diff --git a/javatests/google/registry/webdriver/WebDriverRule.java b/javatests/google/registry/webdriver/WebDriverRule.java new file mode 100644 index 000000000..9dd09b4ba --- /dev/null +++ b/javatests/google/registry/webdriver/WebDriverRule.java @@ -0,0 +1,288 @@ +// Copyright 2017 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 java.util.stream.Collectors.joining; +import static org.apache.commons.text.StringEscapeUtils.escapeEcmaScript; + +import com.google.common.base.Preconditions; +import java.net.URL; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.TimeUnit; +import java.util.function.Predicate; +import org.junit.rules.ExternalResource; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; +import org.openqa.selenium.By; +import org.openqa.selenium.Capabilities; +import org.openqa.selenium.HasCapabilities; +import org.openqa.selenium.JavascriptExecutor; +import org.openqa.selenium.OutputType; +import org.openqa.selenium.TakesScreenshot; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebDriverException; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.interactions.HasInputDevices; +import org.openqa.selenium.interactions.Keyboard; +import org.openqa.selenium.interactions.Mouse; +import org.openqa.selenium.remote.DesiredCapabilities; + +/** WebDriver delegate JUnit Rule that sends Sponge a screenshot on failure. */ +public final class WebDriverRule extends ExternalResource + implements WebDriver, HasInputDevices, TakesScreenshot, JavascriptExecutor, HasCapabilities { + + private static final int WAIT_FOR_ELEMENTS_POLLING_INTERVAL_MS = 10; + private static final int WAIT_FOR_ELEMENTS_BONUS_DELAY_MS = 150; + + // The maximum difference between pixels that would be considered as "identical". Calculated as + // the sum of the absolute difference between the values of the RGB channels. So a 120,30,200 + // reference pixel and a 122,31,193 result pixel have a difference of 10, and would be considered + // identical if MAX_COLOR_DIFF=10 + private static final int MAX_COLOR_DIFF = 10; + + // Percent of pixels that are allowed to be different (more than the MAX_COLOR_DIFF) between the + // images while still considering the test to have passed. Useful if there are a very small + // number of pixels that vary (usually on the corners of "rounded" buttons or similar) + private static final int MAX_PIXEL_DIFF = 0; + + + private WebDriver driver; + private WebDriverPlusScreenDiffer webDriverPlusScreenDiffer; + + // Prefix to use for golden image files, will be set to ClassName_MethodName once the test + // starts. Will be added a user-given imageKey as a suffix, and of course a '.png' at the end. + private String imageNamePrefix = null; + + @Override + public Statement apply(Statement base, Description description) { + if (imageNamePrefix == null) { + String className = description.getTestClass().getSimpleName(); + String methodName = description.getMethodName(); + String unsanitizedName = className + "_" + methodName; + // remove all of the special wildcard characters so they don't exist in filenames. + imageNamePrefix = unsanitizedName.replaceAll("[*?~\"\\[\\]]", ""); + } + return super.apply(base, description); + } + + @Override + protected void before() { + webDriverPlusScreenDiffer = + new ChromeWebDriverPlusScreenDiffer(); + driver = webDriverPlusScreenDiffer.getWebDriver(); + // non-zero timeout so findByElement will wait for the element to appear + driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS); + } + + @Override + protected void after() { + try { + driver.quit(); + } finally { + driver = null; + } + webDriverPlusScreenDiffer.verifyAndQuit(); + } + + /** @see #get(String) */ + public void get(URL url) { + driver.get(url.toString()); + } + + /** Waits indefinitely for an element to appear on the page, then returns it. */ + public WebElement waitForElement(By by) throws InterruptedException { + while (true) { + List elements = findElements(by); + if (!elements.isEmpty()) { + Thread.sleep(WAIT_FOR_ELEMENTS_BONUS_DELAY_MS); + return elements.get(0); + } + Thread.sleep(WAIT_FOR_ELEMENTS_POLLING_INTERVAL_MS); + } + } + + /** Waits for element matching {@code by} whose {@code attribute} satisfies {@code predicate}. */ + public WebElement waitForAttribute( + By by, String attribute, Predicate predicate) + throws InterruptedException { + while (true) { + for (WebElement element : findElements(by)) { + if (predicate.test(element.getAttribute(attribute))) { + Thread.sleep(WAIT_FOR_ELEMENTS_BONUS_DELAY_MS); + return element; + } + } + Thread.sleep(WAIT_FOR_ELEMENTS_POLLING_INTERVAL_MS); + } + } + + /** Sets value of input fields, where {@code fields} key is the {@code id=""} attribute. */ + public void setFormFieldsById(Map fields) { + executeScript( + fields.entrySet().stream() + .map( + entry -> + String.format( + "document.getElementById('%s').value = '%s';", + escapeEcmaScript(entry.getKey()), escapeEcmaScript(entry.getValue()))) + .collect(joining("\n"))); + } + + /** + * Checks that the screenshot of the element matches the golden image by pixel comparison. + * + *

On mismatch, the test will continue until the end of the test (and then fail). This is so + * other screenshot matches can be executed in the same function - allowing you to approve / + * reject all at once. + * + * @param imageKey a unique name such that by prepending the calling class name and method name in + * the format of ClassName_MethodName_ will uniquely identify golden image. + * @param element the element on the page to be compared + */ + public void diffElement(String imageKey, WebElement element) { + webDriverPlusScreenDiffer.diffElement(getUniqueName(imageKey), element); + } + + /** + * Checks that the screenshot of the element matches the golden image by pixel comparison. + * + *

On mismatch, the test will continue until the end of the test (and then fail). This is so + * other screenshot matches can be executed in the same function - allowing you to approve / + * reject all at once. + * + * @param imageKey a unique name such that by prepending the calling class name and method name in + * the format of ClassName_MethodName_ will uniquely identify golden image. + * @param by {@link By} which locates the element on the page to be compared + */ + public void diffElement(String imageKey, By by) { + diffElement(imageKey, driver.findElement(by)); + } + + /** + * Checks that the screenshot matches the golden image by pixel comparison. + * + *

On mismatch, the test will continue until the end of the test (and then fail). This is so + * other screenshot matches can be executed in the same function - allowing you to approve / + * reject all at once. + * + * @param imageKey a unique name such that by prepending the calling class name and method name in + * the format of ClassName_MethodName_ will uniquely identify golden image. + */ + public void diffPage(String imageKey) { + webDriverPlusScreenDiffer.diffPage(getUniqueName(imageKey)); + } + + @Override + public void get(String url) { + driver.get(url); + } + + @Override + public String getCurrentUrl() { + return driver.getCurrentUrl(); + } + + @Override + public String getTitle() { + return driver.getTitle(); + } + + @Override + public List findElements(By by) { + return driver.findElements(by); + } + + @Override + public WebElement findElement(By by) { + return driver.findElement(by); + } + + @Override + public String getPageSource() { + return driver.getPageSource(); + } + + @Override + public void close() { + driver.close(); + } + + @Override + public void quit() { + driver.quit(); + } + + @Override + public Set getWindowHandles() { + return driver.getWindowHandles(); + } + + @Override + public String getWindowHandle() { + return driver.getWindowHandle(); + } + + @Override + public TargetLocator switchTo() { + return driver.switchTo(); + } + + @Override + public Navigation navigate() { + return driver.navigate(); + } + + @Override + public Options manage() { + return driver.manage(); + } + + @Override + public Keyboard getKeyboard() { + return ((HasInputDevices) driver).getKeyboard(); + } + + @Override + public Mouse getMouse() { + return ((HasInputDevices) driver).getMouse(); + } + + @Override + public X getScreenshotAs(OutputType target) throws WebDriverException { + return ((TakesScreenshot) driver).getScreenshotAs(target); + } + + @Override + public Object executeScript(String script, Object... args) { + return ((JavascriptExecutor) driver).executeScript(script, args); + } + + @Override + public Object executeAsyncScript(String script, Object... args) { + return ((JavascriptExecutor) driver).executeAsyncScript(script, args); + } + + @Override + public Capabilities getCapabilities() { + return new DesiredCapabilities(); + } + + private String getUniqueName(String imageKey) { + Preconditions.checkNotNull(imageNamePrefix); + return imageNamePrefix + "_" + imageKey; + } +} diff --git a/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/OteSetupConsoleScreenshotTest_get_admin_fails_badEmail_oteResultFailed.png b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/OteSetupConsoleScreenshotTest_get_admin_fails_badEmail_oteResultFailed.png new file mode 100644 index 000000000..ee59260b7 Binary files /dev/null and b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/OteSetupConsoleScreenshotTest_get_admin_fails_badEmail_oteResultFailed.png differ diff --git a/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/OteSetupConsoleScreenshotTest_get_admin_succeeds_formEmpty.png b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/OteSetupConsoleScreenshotTest_get_admin_succeeds_formEmpty.png new file mode 100644 index 000000000..7b1b6d5da Binary files /dev/null and b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/OteSetupConsoleScreenshotTest_get_admin_succeeds_formEmpty.png differ diff --git a/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/OteSetupConsoleScreenshotTest_get_admin_succeeds_formFilled.png b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/OteSetupConsoleScreenshotTest_get_admin_succeeds_formFilled.png new file mode 100644 index 000000000..28dee0768 Binary files /dev/null and b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/OteSetupConsoleScreenshotTest_get_admin_succeeds_formFilled.png differ diff --git a/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/OteSetupConsoleScreenshotTest_get_admin_succeeds_oteResult.png b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/OteSetupConsoleScreenshotTest_get_admin_succeeds_oteResult.png new file mode 100644 index 000000000..c8de1356a Binary files /dev/null and b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/OteSetupConsoleScreenshotTest_get_admin_succeeds_oteResult.png differ diff --git a/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/OteSetupConsoleScreenshotTest_get_owner_fails_unauthorized.png b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/OteSetupConsoleScreenshotTest_get_owner_fails_unauthorized.png new file mode 100644 index 000000000..752724dd7 Binary files /dev/null and b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/OteSetupConsoleScreenshotTest_get_owner_fails_unauthorized.png differ diff --git a/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/PaymentScreenshotTest_badAmount_showsError_page.png b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/PaymentScreenshotTest_badAmount_showsError_page.png new file mode 100644 index 000000000..1b87eba0c Binary files /dev/null and b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/PaymentScreenshotTest_badAmount_showsError_page.png differ diff --git a/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/PaymentScreenshotTest_form_page.png b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/PaymentScreenshotTest_form_page.png new file mode 100644 index 000000000..8651b6f23 Binary files /dev/null and b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/PaymentScreenshotTest_form_page.png differ diff --git a/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/PaymentScreenshotTest_goodAmount_displaySuccess_page.png b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/PaymentScreenshotTest_goodAmount_displaySuccess_page.png new file mode 100644 index 000000000..5e957bec4 Binary files /dev/null and b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/PaymentScreenshotTest_goodAmount_displaySuccess_page.png differ diff --git a/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_consoleDisabled_page.png b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_consoleDisabled_page.png new file mode 100644 index 000000000..270fe56c8 Binary files /dev/null and b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_consoleDisabled_page.png differ diff --git a/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_contactCreate_page.png b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_contactCreate_page.png new file mode 100644 index 000000000..82cde8cb4 Binary files /dev/null and b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_contactCreate_page.png differ diff --git a/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_contactEdit_page.png b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_contactEdit_page.png new file mode 100644 index 000000000..3b33231c1 Binary files /dev/null and b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_contactEdit_page.png differ diff --git a/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_contactUs_page.png b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_contactUs_page.png new file mode 100644 index 000000000..3b9aa578f Binary files /dev/null and b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_contactUs_page.png differ diff --git a/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_contactView_page.png b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_contactView_page.png new file mode 100644 index 000000000..d5440cab3 Binary files /dev/null and b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_contactView_page.png differ diff --git a/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_domainCreate_page.png b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_domainCreate_page.png new file mode 100644 index 000000000..9d44299dd Binary files /dev/null and b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_domainCreate_page.png differ diff --git a/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_domainEdit_page.png b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_domainEdit_page.png new file mode 100644 index 000000000..d08a76914 Binary files /dev/null and b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_domainEdit_page.png differ diff --git a/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_domainView_page.png b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_domainView_page.png new file mode 100644 index 000000000..1a42e1056 Binary files /dev/null and b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_domainView_page.png differ diff --git a/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_getOteStatus_completed_before_click.png b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_getOteStatus_completed_before_click.png new file mode 100644 index 000000000..e07cc2c43 Binary files /dev/null and b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_getOteStatus_completed_before_click.png differ diff --git a/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_getOteStatus_completed_result.png b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_getOteStatus_completed_result.png new file mode 100644 index 000000000..c00503d54 Binary files /dev/null and b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_getOteStatus_completed_result.png differ diff --git a/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_getOteStatus_noButtonWhenReal_result.png b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_getOteStatus_noButtonWhenReal_result.png new file mode 100644 index 000000000..172acbf64 Binary files /dev/null and b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_getOteStatus_noButtonWhenReal_result.png differ diff --git a/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_getOteStatus_notCompleted_result.png b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_getOteStatus_notCompleted_result.png new file mode 100644 index 000000000..f5e90216e Binary files /dev/null and b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_getOteStatus_notCompleted_result.png differ diff --git a/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_hostCreate_page.png b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_hostCreate_page.png new file mode 100644 index 000000000..99bc7cb4b Binary files /dev/null and b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_hostCreate_page.png differ diff --git a/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_hostEdit_page.png b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_hostEdit_page.png new file mode 100644 index 000000000..1eac7717b Binary files /dev/null and b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_hostEdit_page.png differ diff --git a/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_hostView_page.png b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_hostView_page.png new file mode 100644 index 000000000..38211994b Binary files /dev/null and b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_hostView_page.png differ diff --git a/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_indexPage_smallScrolledDown_page.png b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_indexPage_smallScrolledDown_page.png new file mode 100644 index 000000000..196b557c5 Binary files /dev/null and b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_indexPage_smallScrolledDown_page.png differ diff --git a/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_index_adminAndOwner_page.png b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_index_adminAndOwner_page.png new file mode 100644 index 000000000..4d18c5f32 Binary files /dev/null and b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_index_adminAndOwner_page.png differ diff --git a/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_index_admin_page.png b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_index_admin_page.png new file mode 100644 index 000000000..23e0ad850 Binary files /dev/null and b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_index_admin_page.png differ diff --git a/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_index_owner_page.png b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_index_owner_page.png new file mode 100644 index 000000000..0131ee7ee Binary files /dev/null and b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_index_owner_page.png differ diff --git a/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_index_page.png b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_index_page.png new file mode 100644 index 000000000..f5c58a973 Binary files /dev/null and b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_index_page.png differ diff --git a/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_settingsAdmin_whenAdmin_edit.png b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_settingsAdmin_whenAdmin_edit.png new file mode 100644 index 000000000..111ff07a2 Binary files /dev/null and b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_settingsAdmin_whenAdmin_edit.png differ diff --git a/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_settingsAdmin_whenAdmin_view.png b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_settingsAdmin_whenAdmin_view.png new file mode 100644 index 000000000..89529d0b2 Binary files /dev/null and b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_settingsAdmin_whenAdmin_view.png differ diff --git a/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_settingsAdmin_whenNotAdmin_showsHome_view.png b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_settingsAdmin_whenNotAdmin_showsHome_view.png new file mode 100644 index 000000000..3b535cbb6 Binary files /dev/null and b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_settingsAdmin_whenNotAdmin_showsHome_view.png differ diff --git a/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_settingsContactEdit_page.png b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_settingsContactEdit_page.png new file mode 100644 index 000000000..fbd90563f Binary files /dev/null and b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_settingsContactEdit_page.png differ diff --git a/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_settingsContactItem_asAdmin_page.png b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_settingsContactItem_asAdmin_page.png new file mode 100644 index 000000000..cf4c45650 Binary files /dev/null and b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_settingsContactItem_asAdmin_page.png differ diff --git a/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_settingsContactItem_page.png b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_settingsContactItem_page.png new file mode 100644 index 000000000..9d08b20e9 Binary files /dev/null and b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_settingsContactItem_page.png differ diff --git a/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_settingsContact_asAdmin_page.png b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_settingsContact_asAdmin_page.png new file mode 100644 index 000000000..97e17b837 Binary files /dev/null and b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_settingsContact_asAdmin_page.png differ diff --git a/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_settingsContact_page.png b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_settingsContact_page.png new file mode 100644 index 000000000..970a7893d Binary files /dev/null and b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_settingsContact_page.png differ diff --git a/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_settingsSecurityWithCerts_edit.png b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_settingsSecurityWithCerts_edit.png new file mode 100644 index 000000000..9383e444c Binary files /dev/null and b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_settingsSecurityWithCerts_edit.png differ diff --git a/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_settingsSecurityWithCerts_view.png b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_settingsSecurityWithCerts_view.png new file mode 100644 index 000000000..c5df9a411 Binary files /dev/null and b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_settingsSecurityWithCerts_view.png differ diff --git a/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_settingsSecurityWithHashOnly_edit.png b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_settingsSecurityWithHashOnly_edit.png new file mode 100644 index 000000000..668956423 Binary files /dev/null and b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_settingsSecurityWithHashOnly_edit.png differ diff --git a/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_settingsSecurityWithHashOnly_view.png b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_settingsSecurityWithHashOnly_view.png new file mode 100644 index 000000000..7a0e19cfd Binary files /dev/null and b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_settingsSecurityWithHashOnly_view.png differ diff --git a/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_settingsSecurity_asAdmin_view.png b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_settingsSecurity_asAdmin_view.png new file mode 100644 index 000000000..29564766a Binary files /dev/null and b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_settingsSecurity_asAdmin_view.png differ diff --git a/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_settingsSecurity_edit.png b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_settingsSecurity_edit.png new file mode 100644 index 000000000..bb7d739e6 Binary files /dev/null and b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_settingsSecurity_edit.png differ diff --git a/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_settingsSecurity_view.png b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_settingsSecurity_view.png new file mode 100644 index 000000000..35c9e5ed3 Binary files /dev/null and b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_settingsSecurity_view.png differ diff --git a/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_settingsWhoisEditError_page.png b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_settingsWhoisEditError_page.png new file mode 100644 index 000000000..e6eb1d39e Binary files /dev/null and b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_settingsWhoisEditError_page.png differ diff --git a/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_settingsWhoisEdit_page.png b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_settingsWhoisEdit_page.png new file mode 100644 index 000000000..7c0504bba Binary files /dev/null and b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_settingsWhoisEdit_page.png differ diff --git a/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_settingsWhois_page.png b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_settingsWhois_page.png new file mode 100644 index 000000000..511dda78c Binary files /dev/null and b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarConsoleScreenshotTest_settingsWhois_page.png differ diff --git a/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarCreateConsoleScreenshotTest_get_admin_fails_badEmail_createResultFailed.png b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarCreateConsoleScreenshotTest_get_admin_fails_badEmail_createResultFailed.png new file mode 100644 index 000000000..a102a0ca0 Binary files /dev/null and b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarCreateConsoleScreenshotTest_get_admin_fails_badEmail_createResultFailed.png differ diff --git a/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarCreateConsoleScreenshotTest_get_admin_succeeds_createResult.png b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarCreateConsoleScreenshotTest_get_admin_succeeds_createResult.png new file mode 100644 index 000000000..285955278 Binary files /dev/null and b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarCreateConsoleScreenshotTest_get_admin_succeeds_createResult.png differ diff --git a/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarCreateConsoleScreenshotTest_get_admin_succeeds_formEmpty.png b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarCreateConsoleScreenshotTest_get_admin_succeeds_formEmpty.png new file mode 100644 index 000000000..e1b9b1cc8 Binary files /dev/null and b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarCreateConsoleScreenshotTest_get_admin_succeeds_formEmpty.png differ diff --git a/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarCreateConsoleScreenshotTest_get_admin_succeeds_formFilled.png b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarCreateConsoleScreenshotTest_get_admin_succeeds_formFilled.png new file mode 100644 index 000000000..29947395b Binary files /dev/null and b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarCreateConsoleScreenshotTest_get_admin_succeeds_formFilled.png differ diff --git a/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarCreateConsoleScreenshotTest_get_owner_fails_unauthorized.png b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarCreateConsoleScreenshotTest_get_owner_fails_unauthorized.png new file mode 100644 index 000000000..752724dd7 Binary files /dev/null and b/javatests/google/registry/webdriver/scuba_goldens/chrome-linux/RegistrarCreateConsoleScreenshotTest_get_owner_fails_unauthorized.png differ