001/*
002 * Copyright 2012-2018 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 *      http://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.boot.test.autoconfigure.web.servlet;
018
019import java.util.concurrent.Executors;
020
021import com.gargoylesoftware.htmlunit.BrowserVersion;
022import org.openqa.selenium.WebDriver;
023import org.openqa.selenium.htmlunit.HtmlUnitDriver;
024
025import org.springframework.boot.autoconfigure.AutoConfigureAfter;
026import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
027import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
028import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
029import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
030import org.springframework.boot.test.web.htmlunit.webdriver.LocalHostWebConnectionHtmlUnitDriver;
031import org.springframework.context.annotation.Bean;
032import org.springframework.context.annotation.Configuration;
033import org.springframework.core.env.Environment;
034import org.springframework.security.concurrent.DelegatingSecurityContextExecutor;
035import org.springframework.test.web.servlet.MockMvc;
036import org.springframework.test.web.servlet.htmlunit.webdriver.MockMvcHtmlUnitDriverBuilder;
037import org.springframework.util.ClassUtils;
038
039/**
040 * Auto-configuration for Selenium {@link WebDriver} MockMVC integration.
041 *
042 * @author Phillip Webb
043 * @since 1.4.0
044 */
045@Configuration
046@ConditionalOnClass(HtmlUnitDriver.class)
047@AutoConfigureAfter(MockMvcAutoConfiguration.class)
048@ConditionalOnProperty(prefix = "spring.test.mockmvc.webdriver", name = "enabled", matchIfMissing = true)
049public class MockMvcWebDriverAutoConfiguration {
050
051        private final Environment environment;
052
053        private static final String SECURITY_CONTEXT_EXECUTOR = "org.springframework.security.concurrent.DelegatingSecurityContextExecutor";
054
055        MockMvcWebDriverAutoConfiguration(Environment environment) {
056                this.environment = environment;
057        }
058
059        @Bean
060        @ConditionalOnMissingBean({ WebDriver.class, MockMvcHtmlUnitDriverBuilder.class })
061        @ConditionalOnBean(MockMvc.class)
062        public MockMvcHtmlUnitDriverBuilder mockMvcHtmlUnitDriverBuilder(MockMvc mockMvc) {
063                return MockMvcHtmlUnitDriverBuilder.mockMvcSetup(mockMvc)
064                                .withDelegate(new LocalHostWebConnectionHtmlUnitDriver(this.environment,
065                                                BrowserVersion.CHROME));
066        }
067
068        @Bean
069        @ConditionalOnMissingBean(WebDriver.class)
070        @ConditionalOnBean(MockMvcHtmlUnitDriverBuilder.class)
071        public HtmlUnitDriver htmlUnitDriver(MockMvcHtmlUnitDriverBuilder builder) {
072                HtmlUnitDriver driver = builder.build();
073                if (ClassUtils.isPresent(SECURITY_CONTEXT_EXECUTOR,
074                                getClass().getClassLoader())) {
075                        driver.setExecutor(new DelegatingSecurityContextExecutor(
076                                        Executors.newSingleThreadExecutor()));
077                }
078                return driver;
079        }
080
081}