Project: aranea
/*
 Copyright 2006 - 2010 Under Dusken 
 
 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 no.dusken.aranea.integration.test; 
 
import com.gargoylesoftware.htmlunit.Page; 
import com.gargoylesoftware.htmlunit.WebResponse; 
import org.apache.http.HttpEntity; 
import org.apache.http.HttpResponse; 
import org.apache.http.NameValuePair; 
import org.apache.http.client.HttpClient; 
import org.apache.http.client.entity.UrlEncodedFormEntity; 
import org.apache.http.client.methods.HttpPost; 
import org.apache.http.impl.client.DefaultHttpClient; 
import org.apache.http.message.BasicNameValuePair; 
import org.codehaus.jackson.map.ObjectMapper; 
import org.junit.After; 
import org.junit.Before; 
import org.openqa.selenium.By; 
import org.openqa.selenium.WebDriver; 
import org.openqa.selenium.WebElement; 
import org.openqa.selenium.htmlunit.HtmlUnitDriver; 
 
import java.io.IOException; 
import java.util.ArrayList; 
import java.util.LinkedList; 
import java.util.List; 
import java.util.Map; 
 
import static junit.framework.Assert.assertEquals; 
import static junit.framework.Assert.fail; 
 
/**
 * @author Marvin B. Lillehaug <[email protected]
 */
 
public abstract class AbstractIntegrationTest { 
 
    protected WebDriver webDriver; 
 
    private String host = "http://localhost:8765"
 
    private HttpClient httpclient; 
    private ObjectMapper mapper; 
 
    private List<String> allowedErrorMessages = new LinkedList<String>(); 
 
    @Before 
    public void before() { 
        webDriver = new HtmlUnitDriver(false){ 
            @Override 
            public WebElement findElement(By by) { 
                WebElement element = super.findElement(by); 
                checkValidity(); 
                return element; 
            } 
 
            @Override 
            public List<WebElement> findElements(By by) { 
                List<WebElement> elements = super.findElements(by); 
                checkValidity(); 
                return elements; 
            } 
            // We do not was content as xml 
            @Override 
            public String getPageSource() { 
                Page page = lastPage(); 
                if (page == null) { 
                    return null
                } 
 
                //if (page instanceof SgmlPage) { 
                //    return ((SgmlPage) page).asXml(); 
                //} 
                WebResponse response = page.getWebResponse(); 
                return response.getContentAsString(); 
            } 
        }; 
        webDriver.get(host); 
 
        httpclient = new DefaultHttpClient(); 
        mapper = new ObjectMapper(); 
 
        allowedErrorMessages.add("Attribute property not allowed on element meta at this point."); 
        allowedErrorMessages.add("Element meta is missing one or more of the following attributes: http-equiv, itemprop, name."); 
        allowedErrorMessages.add("Element fb:like not allowed as child of element div in this context. (Suppressing further errors from this subtree.)"); 
    } 
 
    @After 
    public void after(){ 
        webDriver.close(); 
    } 
 
    /**
     * Send a get command to the webdriver using the host and a relative path. 
     * @param relativePath to add to host. 
     */
 
    protected void getRelativePath(String relativePath) throws IOException { 
        webDriver.get(host + relativePath); 
    } 
 
    private void checkValidity() { 
        try { 
            HttpPost post = new HttpPost("http://validator.w3.org/check"); 
            List<NameValuePair> formparams = new ArrayList<NameValuePair>(); 
            String pageSource = webDriver.getPageSource(); 
            formparams.add(new BasicNameValuePair("fragment", pageSource)); 
            formparams.add(new BasicNameValuePair("output""json")); 
            UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams, "UTF-8"); 
 
            post.setEntity(entity); 
            HttpResponse httpResponse = httpclient.execute(post); 
            HttpEntity responseEntity = httpResponse.getEntity(); 
 
            Map values = mapper.readValue(responseEntity.getContent(), Map.class); 
            checkValues((List<Map<String, Object>>) values.get("messages")); 
        } catch (IOException e) { 
            fail("Error when checking validity: " + e.getMessage()); 
            e.printStackTrace(); 
        } 
    } 
    private void checkValues(List<Map<String, Object>> messages) { 
        StringBuilder errorMessageBuilder = new StringBuilder(); 
        for (Map<String, Object> message : messages){ 
            String type = (String) message.get("type"); 
            String validationmessage = (String) message.get("message"); 
            Integer line = (Integer) message.get("lastLine"); 
            boolean messageIsNotAllowed = !allowedErrorMessages.contains(validationmessage); 
            if("error".equals(type) && messageIsNotAllowed){ 
                errorMessageBuilder.append("Error: ").append(validationmessage).append(" line: ").append(line).append("\n"); 
            } 
        } 
        assertEquals(errorMessageBuilder.toString(), 0, errorMessageBuilder.length()); 
    } 
 
    public String getHost() { 
        return host; 
    } 
}