diff --git a/spring-boot-dependencies/pom.xml b/spring-boot-dependencies/pom.xml index ba50ab1b523..e1dd18c0b47 100644 --- a/spring-boot-dependencies/pom.xml +++ b/spring-boot-dependencies/pom.xml @@ -84,6 +84,7 @@ 2.3.13 2.4.7.Final 2.3.3 + 2.19 4.1.1 4.5.1 4.4.4 @@ -124,6 +125,7 @@ 9.4.1208.jre7 2.0.7.RELEASE 2.0.7.RELEASE + 2.52.0 2.2.2 3.1.0 1.1.1 @@ -932,6 +934,11 @@ ehcache ${ehcache.version} + + net.sourceforge.htmlunit + htmlunit + ${htmlunit.version} + net.sourceforge.jtds jtds @@ -1758,6 +1765,11 @@ lombok ${lombok.version} + + org.seleniumhq.selenium + selenium-htmlunit-driver + ${selenium.version} + org.skyscreamer jsonassert diff --git a/spring-boot-test/pom.xml b/spring-boot-test/pom.xml index a8331732a4a..05373404345 100644 --- a/spring-boot-test/pom.xml +++ b/spring-boot-test/pom.xml @@ -75,6 +75,11 @@ jsonassert true + + org.seleniumhq.selenium + selenium-htmlunit-driver + true + org.springframework spring-test @@ -86,8 +91,8 @@ true - junit - junit + net.sourceforge.htmlunit + htmlunit true diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/web/htmlunit/LocalHostWebClient.java b/spring-boot-test/src/main/java/org/springframework/boot/test/web/htmlunit/LocalHostWebClient.java new file mode 100644 index 00000000000..88395bbebe2 --- /dev/null +++ b/spring-boot-test/src/main/java/org/springframework/boot/test/web/htmlunit/LocalHostWebClient.java @@ -0,0 +1,55 @@ +/* + * Copyright 2012-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 org.springframework.boot.test.web.htmlunit; + +import java.io.IOException; +import java.net.MalformedURLException; + +import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException; +import com.gargoylesoftware.htmlunit.Page; +import com.gargoylesoftware.htmlunit.WebClient; + +import org.springframework.core.env.Environment; +import org.springframework.util.Assert; + +/** + * {@link WebClient} will automatically prefix relative URLs with + * localhost:${local.server.port}. + * + * @author Phillip Webb + * @since 1.4.0 + */ +public class LocalHostWebClient extends WebClient { + + private final Environment environment; + + public LocalHostWebClient(Environment environment) { + Assert.notNull(environment, "Environment must not be null"); + this.environment = environment; + } + + @Override + public

P getPage(String url) + throws IOException, FailingHttpStatusCodeException, MalformedURLException { + if (url.startsWith("/")) { + String port = this.environment.getProperty("local.server.port", "8080"); + url = "http://localhost:" + port + url; + } + return super.getPage(url); + } + +} diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/web/htmlunit/package-info.java b/spring-boot-test/src/main/java/org/springframework/boot/test/web/htmlunit/package-info.java new file mode 100644 index 00000000000..e9c6daa040c --- /dev/null +++ b/spring-boot-test/src/main/java/org/springframework/boot/test/web/htmlunit/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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. + */ + +/** + * HtmlUnit support classes. + */ +package org.springframework.boot.test.web.htmlunit; diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/web/htmlunit/webdriver/LocalHostWebConnectionHtmlUnitDriver.java b/spring-boot-test/src/main/java/org/springframework/boot/test/web/htmlunit/webdriver/LocalHostWebConnectionHtmlUnitDriver.java new file mode 100644 index 00000000000..d2c265e0083 --- /dev/null +++ b/spring-boot-test/src/main/java/org/springframework/boot/test/web/htmlunit/webdriver/LocalHostWebConnectionHtmlUnitDriver.java @@ -0,0 +1,72 @@ +/* + * Copyright 2012-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 org.springframework.boot.test.web.htmlunit.webdriver; + +import com.gargoylesoftware.htmlunit.BrowserVersion; +import org.openqa.selenium.Capabilities; + +import org.springframework.core.env.Environment; +import org.springframework.test.web.servlet.htmlunit.webdriver.WebConnectionHtmlUnitDriver; +import org.springframework.util.Assert; + +/** + * {@link LocalHostWebConnectionHtmlUnitDriver} will automatically prefix relative URLs + * with localhost:${local.server.port}. + * + * @author Phillip Webb + * @since 1.4.0 + */ +public class LocalHostWebConnectionHtmlUnitDriver extends WebConnectionHtmlUnitDriver { + + private final Environment environment; + + public LocalHostWebConnectionHtmlUnitDriver(Environment environment) { + Assert.notNull(environment, "Environment must not be null"); + this.environment = environment; + } + + public LocalHostWebConnectionHtmlUnitDriver(Environment environment, + boolean enableJavascript) { + super(enableJavascript); + Assert.notNull(environment, "Environment must not be null"); + this.environment = environment; + } + + public LocalHostWebConnectionHtmlUnitDriver(Environment environment, + BrowserVersion browserVersion) { + super(browserVersion); + Assert.notNull(environment, "Environment must not be null"); + this.environment = environment; + } + + public LocalHostWebConnectionHtmlUnitDriver(Environment environment, + Capabilities capabilities) { + super(capabilities); + Assert.notNull(environment, "Environment must not be null"); + this.environment = environment; + } + + @Override + public void get(String url) { + if (url.startsWith("/")) { + String port = this.environment.getProperty("local.server.port", "8080"); + url = "http://localhost:" + port + url; + } + super.get(url); + } + +} diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/web/htmlunit/webdriver/package-info.java b/spring-boot-test/src/main/java/org/springframework/boot/test/web/htmlunit/webdriver/package-info.java new file mode 100644 index 00000000000..a80565858e8 --- /dev/null +++ b/spring-boot-test/src/main/java/org/springframework/boot/test/web/htmlunit/webdriver/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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. + */ + +/** + * Selenium support classes. + */ +package org.springframework.boot.test.web.htmlunit.webdriver; diff --git a/spring-boot-test/src/test/java/org/springframework/boot/test/web/htmlunit/LocalHostWebClientTests.java b/spring-boot-test/src/test/java/org/springframework/boot/test/web/htmlunit/LocalHostWebClientTests.java new file mode 100644 index 00000000000..47157812397 --- /dev/null +++ b/spring-boot-test/src/test/java/org/springframework/boot/test/web/htmlunit/LocalHostWebClientTests.java @@ -0,0 +1,101 @@ +/* + * Copyright 2012-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 org.springframework.boot.test.web.htmlunit; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; + +import com.gargoylesoftware.htmlunit.StringWebResponse; +import com.gargoylesoftware.htmlunit.WebClient; +import com.gargoylesoftware.htmlunit.WebConnection; +import com.gargoylesoftware.htmlunit.WebRequest; +import com.gargoylesoftware.htmlunit.WebResponse; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.MockitoAnnotations; + +import org.springframework.mock.env.MockEnvironment; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.BDDMockito.given; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +/** + * Tests for {@link LocalHostWebClient}. + * + * @author Phillip Webb + */ +@SuppressWarnings("resource") +public class LocalHostWebClientTests { + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Captor + private ArgumentCaptor requestCaptor; + + public LocalHostWebClientTests() { + MockitoAnnotations.initMocks(this); + } + + @Test + public void createWhenEnvironmentIsNullWillThrowException() throws Exception { + this.thrown.expect(IllegalArgumentException.class); + this.thrown.expectMessage("Environment must not be null"); + new LocalHostWebClient(null); + } + + @Test + public void getPageWhenUrlIsRelativeAndNoPortWillUseLocalhost8080() throws Exception { + MockEnvironment environment = new MockEnvironment(); + WebClient client = new LocalHostWebClient(environment); + WebConnection connection = mockConnection(); + client.setWebConnection(connection); + client.getPage("/test"); + verify(connection).getResponse(this.requestCaptor.capture()); + assertThat(this.requestCaptor.getValue().getUrl()) + .isEqualTo(new URL("http://localhost:8080/test")); + } + + @Test + public void getPageWhenUrlIsRelativeAndHasPortWillUseLocalhostPort() + throws Exception { + MockEnvironment environment = new MockEnvironment(); + environment.setProperty("local.server.port", "8181"); + WebClient client = new LocalHostWebClient(environment); + WebConnection connection = mockConnection(); + client.setWebConnection(connection); + client.getPage("/test"); + verify(connection).getResponse(this.requestCaptor.capture()); + assertThat(this.requestCaptor.getValue().getUrl()) + .isEqualTo(new URL("http://localhost:8181/test")); + } + + private WebConnection mockConnection() throws MalformedURLException, IOException { + WebConnection connection = mock(WebConnection.class); + WebResponse response = new StringWebResponse("test", new URL("http://localhost")); + given(connection.getResponse((WebRequest) any())).willReturn(response); + return connection; + } + +} diff --git a/spring-boot-test/src/test/java/org/springframework/boot/test/web/htmlunit/webdriver/LocalHostWebConnectionHtmlUnitDriverTests.java b/spring-boot-test/src/test/java/org/springframework/boot/test/web/htmlunit/webdriver/LocalHostWebConnectionHtmlUnitDriverTests.java new file mode 100644 index 00000000000..7e4ee7c6024 --- /dev/null +++ b/spring-boot-test/src/test/java/org/springframework/boot/test/web/htmlunit/webdriver/LocalHostWebConnectionHtmlUnitDriverTests.java @@ -0,0 +1,120 @@ +/* + * Copyright 2012-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 org.springframework.boot.test.web.htmlunit.webdriver; + +import java.net.URL; + +import com.gargoylesoftware.htmlunit.BrowserVersion; +import com.gargoylesoftware.htmlunit.WebClient; +import com.gargoylesoftware.htmlunit.WebClientOptions; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.openqa.selenium.Capabilities; + +import org.springframework.core.env.Environment; +import org.springframework.mock.env.MockEnvironment; + +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +/** + * Tests for {@link LocalHostWebConnectionHtmlUnitDriver}. + * + * @author Phillip Webb + */ +public class LocalHostWebConnectionHtmlUnitDriverTests { + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Mock + private WebClient webClient; + + public LocalHostWebConnectionHtmlUnitDriverTests() { + MockitoAnnotations.initMocks(this); + given(this.webClient.getOptions()).willReturn(new WebClientOptions()); + } + + @Test + public void createWhenEnvironmentIsNullWillThrowException() throws Exception { + this.thrown.expect(IllegalArgumentException.class); + this.thrown.expectMessage("Environment must not be null"); + new LocalHostWebConnectionHtmlUnitDriver(null); + } + + @Test + public void createWithJavascriptFlagWhenEnvironmentIsNullWillThrowException() + throws Exception { + this.thrown.expect(IllegalArgumentException.class); + this.thrown.expectMessage("Environment must not be null"); + new LocalHostWebConnectionHtmlUnitDriver(null, true); + } + + @Test + public void createWithBrowserVersionWhenEnvironmentIsNullWillThrowException() + throws Exception { + this.thrown.expect(IllegalArgumentException.class); + this.thrown.expectMessage("Environment must not be null"); + new LocalHostWebConnectionHtmlUnitDriver(null, BrowserVersion.CHROME); + } + + @Test + public void createWithCapabilitiesWhenEnvironmentIsNullWillThrowException() + throws Exception { + this.thrown.expect(IllegalArgumentException.class); + this.thrown.expectMessage("Environment must not be null"); + new LocalHostWebConnectionHtmlUnitDriver(null, mock(Capabilities.class)); + } + + @Test + public void getPageWhenUrlIsRelativeAndNoPortWillUseLocalhost8080() throws Exception { + MockEnvironment environment = new MockEnvironment(); + LocalHostWebConnectionHtmlUnitDriver driver = new TestLocalHostWebConnectionHtmlUnitDriver( + environment); + driver.get("/test"); + verify(this.webClient).getPage(new URL("http://localhost:8080/test")); + } + + @Test + public void getWhenUrlIsRelativeAndHasPortWillUseLocalhostPort() throws Exception { + MockEnvironment environment = new MockEnvironment(); + environment.setProperty("local.server.port", "8181"); + LocalHostWebConnectionHtmlUnitDriver driver = new TestLocalHostWebConnectionHtmlUnitDriver( + environment); + driver.get("/test"); + verify(this.webClient).getPage(new URL("http://localhost:8181/test")); + } + + public class TestLocalHostWebConnectionHtmlUnitDriver + extends LocalHostWebConnectionHtmlUnitDriver { + + public TestLocalHostWebConnectionHtmlUnitDriver(Environment environment) { + super(environment); + } + + @Override + public WebClient getWebClient() { + return LocalHostWebConnectionHtmlUnitDriverTests.this.webClient; + } + + } + +}