Archive for July, 2009

Assert image presence on page with Selenium

Assume you have some images on your page under test, which has some images. You should be sure they are really displayed. Simple validation on image control presence doesn’t solves the problem, because <img> could have invalid source (src attribute). We will enhance our basic test with method which could be used like:

assertImagePresent("imgUnderTestId")

assertImagePresent() method could be used with img component id or with XPath locator to assert that image has nonzero width and height (such technique used because width and height under assertion are real dimensions of target image in already rendered page).

We will enhance our basic SeleniumTest (used as superclass for all integration test cases) again:

public abstract class SeleniumTest extends SeleneseTestCase {
    static String context = "http://localhost:8080/app/"

    public void setUp() {
        setUp context, "*firefox"
    }
    ...
    def assertImagePresent(String imageIdOrXPathLocator) {
        assertTrue Integer.valueOf(getDomAttribute(imageIdOrXPathLocator, "naturalWidth")) > 0
        assertTrue Integer.valueOf(getDomAttribute(imageIdOrXPathLocator, "naturalHeight")) > 0
    }

    def getDomAttribute(String elementIdOrXPathLocator, String attribute) {
        if (elementIdOrXPathLocator.startsWith("//")) {
            def expression = "window.document.evaluate('${StringEscapeUtils.escapeJavaScript(elementIdOrXPathLocator)}', window.document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue['$attribute'];"
            return selenium.getEval(expression)
        } else {
            return selenium.getEval("window.document.getElementById('$elementIdOrXPathLocator')['$attribute'];")
        }
    }
    ...
}

Tags: , , , ,

Adding WebFlow support to Maven driven Grails project

It’s just simple tip, but you could find it useful if you noob in Maven. WebFlow comes with Grails by default, but since we develop with Maven we should include this dependency manually. Just modify your Grails project pom.xml dependencies by including webflow reference:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    ...
    <dependencies>
        ...
        <dependency>
            <groupId>org.grails</groupId>
            <artifactId>grails-webflow</artifactId>
            <version>1.1.1</version>
        </dependency>
        ...
    </dependencies>
    ...
</project>

Tags: , ,

Attaching file to file upload control with Selenium (via JavaScript)

I didn’t found useful way to set file inputs controls in our integration tests written with Selenium. I propose JavaScript way to execute with Selenium RC to achieve this. Finally this should be doable with following code in any Test Case:

setFile "fileInputId", getResourcePath("some photo.jpg")

getResourcePath() – returns path to resource (java/groovy resources meant). You could use any path string instead, but inclusion of resources (test resources) is more convenient, because they become part of your test environment. If you have some problems with java/groovy resources, feel free to ask.

* We will extend our SeleniumTest (basic class for all integration tests with this method:

public abstract class SeleniumTest extends SeleneseTestCase {
    static String context = "http://localhost:8080/app/"

    public void setUp() {
        setUp context, "*firefox"
    }
    ...
    void setFile(String fileInputId, String fileName) {
        selenium.getEval(
            """var imageControl = window.document.getElementById('${fileInputId}');
               imageControl.value='$fileName';
               var event = window.document.createEvent('HTMLEvents');
               event.initEvent('change',true,true);
               imageControl.dispatchEvent(event);
            """)
    }

    String getResourcePath(String resourcePath) {
        getClass().getResource(resourcePath).getPath()
    }
    ...
}

This method uses document model to inject file path into HTML file input control and also generates onChange event, which could be useful if onChange event handler defined for this component.

Tags: , , ,

CSS convention for Grails

As far as our CSS styles grow I found that there should intuitive way to manage CSS inclusions. I’ve decided to follow great Grails fundamental idea and place them by some convention and include automagically.

We found useful to have separate CSS for each view (or controller action if you wish). Convention is simple: place each CSS in the same path as you place your views under /views folder.

For example, we have view: /views/picture/gallery.gsp and want to have gallery.css which contains all styles for this view. We should place it in the same path as our view located, in our example it should be /web-app/css/picture/gallery.css. Now to automatically include such CSSs by convention we should modify our main layout (/views/layouts/main.gsp) next way:

<head>
...
<% if (webRequest.controllerName && webRequest.actionName) { %>
    <link rel="stylesheet" href="${resource(dir: 'css/' + webRequest.getControllerName(), file: webRequest.getActionName() + '.css')}"/>
<% } %>
...
</head>

All further CSSs placed by this convention will be automatically included for each action (which uses main layout) . If you have more layouts you could modify them same way. Anyway their count will be much less than your actions/views count.

Hope this helps. If you have some ideas to improve this approach or you use some other approach, please share :)



                      

Tags: ,