001/* 002 * Copyright 2002-2016 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.test.web.servlet.htmlunit.webdriver; 018 019import com.gargoylesoftware.htmlunit.BrowserVersion; 020import com.gargoylesoftware.htmlunit.WebClient; 021import org.openqa.selenium.htmlunit.HtmlUnitDriver; 022 023import org.springframework.test.web.servlet.MockMvc; 024import org.springframework.test.web.servlet.htmlunit.MockMvcWebConnectionBuilderSupport; 025import org.springframework.test.web.servlet.htmlunit.WebRequestMatcher; 026import org.springframework.test.web.servlet.setup.MockMvcConfigurer; 027import org.springframework.util.Assert; 028import org.springframework.web.context.WebApplicationContext; 029 030/** 031 * {@code MockMvcHtmlUnitDriverBuilder} simplifies the building of an 032 * {@link HtmlUnitDriver} that delegates to {@link MockMvc} and optionally 033 * delegates to an actual connection for specific requests. 034 * 035 * <p>By default, the driver will delegate to {@code MockMvc} to handle 036 * requests to {@code localhost} and to a {@link WebClient} to handle any 037 * other URL (i.e. to perform an actual HTTP request). 038 * 039 * @author Rob Winch 040 * @author Sam Brannen 041 * @since 4.2 042 * @see #mockMvcSetup(MockMvc) 043 * @see #webAppContextSetup(WebApplicationContext) 044 * @see #webAppContextSetup(WebApplicationContext, MockMvcConfigurer) 045 * @see #javascriptEnabled(boolean) 046 * @see #withDelegate(WebConnectionHtmlUnitDriver) 047 * @see #build() 048 */ 049public class MockMvcHtmlUnitDriverBuilder extends MockMvcWebConnectionBuilderSupport<MockMvcHtmlUnitDriverBuilder> { 050 051 private HtmlUnitDriver driver; 052 053 private boolean javascriptEnabled = true; 054 055 056 protected MockMvcHtmlUnitDriverBuilder(MockMvc mockMvc) { 057 super(mockMvc); 058 } 059 060 protected MockMvcHtmlUnitDriverBuilder(WebApplicationContext context) { 061 super(context); 062 } 063 064 protected MockMvcHtmlUnitDriverBuilder(WebApplicationContext context, MockMvcConfigurer configurer) { 065 super(context, configurer); 066 } 067 068 069 /** 070 * Create a new {@code MockMvcHtmlUnitDriverBuilder} based on the supplied 071 * {@link MockMvc} instance. 072 * @param mockMvc the {@code MockMvc} instance to use (never {@code null}) 073 * @return the MockMvcHtmlUnitDriverBuilder to customize 074 */ 075 public static MockMvcHtmlUnitDriverBuilder mockMvcSetup(MockMvc mockMvc) { 076 Assert.notNull(mockMvc, "MockMvc must not be null"); 077 return new MockMvcHtmlUnitDriverBuilder(mockMvc); 078 } 079 080 /** 081 * Create a new {@code MockMvcHtmlUnitDriverBuilder} based on the supplied 082 * {@link WebApplicationContext}. 083 * @param context the {@code WebApplicationContext} to create a {@link MockMvc} 084 * instance from (never {@code null}) 085 * @return the MockMvcHtmlUnitDriverBuilder to customize 086 */ 087 public static MockMvcHtmlUnitDriverBuilder webAppContextSetup(WebApplicationContext context) { 088 Assert.notNull(context, "WebApplicationContext must not be null"); 089 return new MockMvcHtmlUnitDriverBuilder(context); 090 } 091 092 /** 093 * Create a new {@code MockMvcHtmlUnitDriverBuilder} based on the supplied 094 * {@link WebApplicationContext} and {@link MockMvcConfigurer}. 095 * @param context the {@code WebApplicationContext} to create a {@link MockMvc} 096 * instance from (never {@code null}) 097 * @param configurer the {@code MockMvcConfigurer} to apply (never {@code null}) 098 * @return the MockMvcHtmlUnitDriverBuilder to customize 099 */ 100 public static MockMvcHtmlUnitDriverBuilder webAppContextSetup(WebApplicationContext context, 101 MockMvcConfigurer configurer) { 102 103 Assert.notNull(context, "WebApplicationContext must not be null"); 104 Assert.notNull(configurer, "MockMvcConfigurer must not be null"); 105 return new MockMvcHtmlUnitDriverBuilder(context, configurer); 106 } 107 108 /** 109 * Specify whether JavaScript should be enabled. 110 * <p>Default is {@code true}. 111 * @param javascriptEnabled {@code true} if JavaScript should be enabled 112 * @return this builder for further customizations 113 * @see #build() 114 */ 115 public MockMvcHtmlUnitDriverBuilder javascriptEnabled(boolean javascriptEnabled) { 116 this.javascriptEnabled = javascriptEnabled; 117 return this; 118 } 119 120 /** 121 * Supply the {@code WebConnectionHtmlUnitDriver} that the driver 122 * {@linkplain #build built} by this builder should delegate to when 123 * processing non-{@linkplain WebRequestMatcher matching} requests. 124 * @param driver the {@code WebConnectionHtmlUnitDriver} to delegate to 125 * for requests that do not match (never {@code null}) 126 * @return this builder for further customizations 127 * @see #build() 128 */ 129 public MockMvcHtmlUnitDriverBuilder withDelegate(WebConnectionHtmlUnitDriver driver) { 130 Assert.notNull(driver, "HtmlUnitDriver must not be null"); 131 driver.setJavascriptEnabled(this.javascriptEnabled); 132 driver.setWebConnection(createConnection(driver.getWebClient())); 133 this.driver = driver; 134 return this; 135 } 136 137 /** 138 * Build the {@link HtmlUnitDriver} configured via this builder. 139 * <p>The returned driver will use the configured {@link MockMvc} instance 140 * for processing any {@linkplain WebRequestMatcher matching} requests 141 * and a delegate {@code HtmlUnitDriver} for all other requests. 142 * <p>If a {@linkplain #withDelegate delegate} has been explicitly configured, 143 * it will be used; otherwise, a default {@code WebConnectionHtmlUnitDriver} 144 * with the {@link BrowserVersion} set to {@link BrowserVersion#CHROME CHROME} 145 * will be configured as the delegate. 146 * @return the {@code HtmlUnitDriver} to use 147 * @see #withDelegate(WebConnectionHtmlUnitDriver) 148 */ 149 public HtmlUnitDriver build() { 150 return (this.driver != null ? this.driver : 151 withDelegate(new WebConnectionHtmlUnitDriver(BrowserVersion.CHROME)).build()); 152 } 153 154}