Search code examples
xmlgroovyxsdwebtestcanoo-webtest

Validate a webpage against its doctype (dtd) within a Canoo Webtest step using a Groovy script


How can I validate a webpage against its doctype (dtd) within a Canoo Webtest step with Groovy?


Solution

  • Actually I know the answer. But as it took me a while to get it working, I thought I'd share my solution. It's a webtest macro. You can also only use the sequential if you like...

    <macrodef name="verifySchema" description="Validate the current document against its schema">
    <sequential>
        <groovy description="validate schema" >
            import javax.xml.parsers.ParserConfigurationException
            import javax.xml.parsers.SAXParser
            import javax.xml.parsers.SAXParserFactory
    
            import java.io.InputStreamReader
    
    
            import org.xml.sax.ErrorHandler
            import org.xml.sax.InputSource
            import org.xml.sax.SAXException
            import org.xml.sax.SAXParseException
            import org.xml.sax.XMLReader
    
            class MyHandler implements org.xml.sax.ErrorHandler {
                void warning(SAXParseException e) throws SAXException {
                    println 'WARNING: ' + e.getMessage()
                }
    
                void error(SAXParseException e) throws SAXException {
                    println 'ERROR: ' + e.getMessage()
                    throw e
                }
    
                void fatalError(SAXParseException e) throws SAXException {
                    println 'FATAL: ' + e.getMessage()
                    throw e
                }
            }
    
    
                def factory = SAXParserFactory.newInstance()
                factory.setValidating(true)
                factory.setNamespaceAware(true)
    
                def parser = factory.newSAXParser()
                def reader = parser.getXMLReader()
                reader.setErrorHandler(new MyHandler())
                def response = step.context.currentResponse.webResponse
                reader.parse(new InputSource(new InputStreamReader(response.contentAsStream,"UTF-8")))
        </groovy>
    </sequential>
    

    If you want to fail your test on warnings too, add a throw statement to the handler accordingly.