001/*
002 * (C) Copyright 2006-2011 Nuxeo SA (http://nuxeo.com/) and contributors.
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 * Contributors:
017 *     Damien Metzler (Leroy Merlin, http://www.leroymerlin.fr/)
018 */
019package org.nuxeo.runtime.test.runner.web;
020
021import org.apache.commons.logging.Log;
022import org.apache.commons.logging.LogFactory;
023import org.junit.runner.Description;
024import org.junit.runner.manipulation.Filter;
025import org.junit.runner.manipulation.NoTestsRemainException;
026import org.nuxeo.runtime.test.runner.FeaturesRunner;
027import org.nuxeo.runtime.test.runner.SimpleFeature;
028import org.openqa.selenium.WebDriver;
029import org.openqa.selenium.support.PageFactory;
030
031import com.google.inject.Binder;
032import com.google.inject.Provider;
033import com.google.inject.Scopes;
034
035public class WebDriverFeature extends SimpleFeature {
036
037    private static final Log log = LogFactory.getLog(WebDriverFeature.class);
038
039    protected Configuration config;
040
041    protected Class<? extends WebPage> home;
042
043    @Override
044    public void initialize(FeaturesRunner runner) throws Exception {
045        Class<?> classToTest = runner.getTargetTestClass();
046        Browser browser = FeaturesRunner.getScanner().getFirstAnnotation(classToTest, Browser.class);
047        DriverFactory factory;
048        // test here if the driver factory is specified by environment
049        String fcName = System.getProperty(DriverFactory.class.getName());
050        if (fcName != null) {
051            factory = (DriverFactory) Class.forName(fcName).newInstance();
052        } else {
053            if (browser == null) {
054                factory = BrowserFamily.HTML_UNIT.getDriverFactory();
055            } else {
056                Class<? extends DriverFactory> fc = browser.factory();
057                if (fc == DriverFactory.class) {
058                    factory = browser.type().getDriverFactory();
059                } else {
060                    factory = fc.newInstance();
061                }
062            }
063        }
064        config = new Configuration(factory);
065
066        // get the home page and the url - first check for an url from the
067        // environment
068        String url = System.getProperty(HomePage.class.getName() + ".url");
069        HomePage home = FeaturesRunner.getScanner().getFirstAnnotation(classToTest, HomePage.class);
070        if (home != null) {
071            config.setHomePageClass(home.type());
072            if (url == null) {
073                url = home.url();
074            }
075        }
076        config.setHome(url);
077        try {
078            runner.filter(new Filter() {
079                @Override
080                public boolean shouldRun(Description description) {
081                    SkipBrowser skip = description.getAnnotation(SkipBrowser.class);
082                    if (skip == null) {
083                        return true;
084                    }
085                    for (BrowserFamily family : skip.value()) {
086                        if (config.getBrowserFamily().equals(family)) {
087                            return false;
088                        }
089                    }
090                    return true;
091                }
092
093                @Override
094                public String describe() {
095                    return "Filtering tests according to current browser settings";
096                }
097            });
098        } catch (ClassCastException e) {
099            // OK - just skip
100        } catch (NoTestsRemainException e) {
101            log.error(e.toString(), e);
102        }
103    }
104
105    @SuppressWarnings("unchecked")
106    @Override
107    public void configure(final FeaturesRunner runner, Binder binder) {
108        binder.bind(Configuration.class).toInstance(config);
109        binder.bind(WebDriver.class).toProvider(new Provider<WebDriver>() {
110            @Override
111            public WebDriver get() {
112                return config.getDriver();
113            }
114        });
115        if (config.getHomePageClass() != null) {
116            binder.bind(config.getHomePageClass()).toProvider(new Provider() {
117                @Override
118                public Object get() {
119                    Object obj = PageFactory.initElements(config.getDriver(), config.getHomePageClass());
120                    runner.getInjector().injectMembers(obj);
121                    if (obj instanceof WebPage) {
122                        ((WebPage) obj).ensureLoaded();
123                    }
124                    return obj;
125                }
126            }).in(Scopes.SINGLETON);
127        }
128    }
129
130    @Override
131    public void stop(FeaturesRunner runner) throws Exception {
132        config.resetDriver();
133        WebPage.flushPageCache();
134    }
135
136}