Galen is a layout testing framework developed by Ivan Shubin. It is an open-source project that you can support (https://github.com/galenframework/galen ).
- It is an automated layout and responsive testing framework.
- Tests locations of objects relatively to each other on the page.
- Runs in Selenium Grid. (SauceLabs & BrowserStack)
You can test responsive websites on different mobile devices. - Supports Parallel Testing
Thus, tests run faster and we save time. - Responsive Design Tests are easy with Galen.
Opens -> Resizes -> Tests with given specifications. - Galen has an own DSL which specifies the constraints about the layout design.
Programming Language Support?
- Basic Syntax
- JavaScript Tests
- Java & Selenium Webdriver
Galen Reporting
- Error Reporting
Generates Html reports where you can see all your test objects. - ScreenShots
Highlights the misaligned elements. - Image Comparison
Compares images and shows differences
Galen Example with JAVA & Webdriver
Note: You can find source code of the sample project at below page:
https://github.com/swtestacademy/galenswtestacademy
Step-1: Add Galen Maven Dependency to the pom.xml
<dependencies> <dependency> <groupId>com.galenframework</groupId> <artifactId>galen-java-support</artifactId> <version>2.0.3</version> </dependency> </dependencies>
Step-2: Create a Selenium Maven Test Project
Create an empty test class as shown below:
Resize the browser for 1200×800 resolution and go to firebrick-termite-918071.hostingersite.com:
import com.galenframework.api.Galen; import com.galenframework.reports.GalenTestInfo; import com.galenframework.reports.HtmlReportBuilder; import com.galenframework.reports.model.LayoutReport; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.openqa.selenium.Dimension; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; import java.io.IOException; import java.util.Arrays; import java.util.LinkedList; import java.util.List; /** * Created by can on 29/01/17. */ public class GalenExampleTest { private WebDriver driver; @Before public void setUp() { //Create a Chrome Driver driver = new ChromeDriver(); //Set the browser size for desktop driver.manage().window().setSize(new Dimension(1200, 800)); //Go to firebrick-termite-918071.hostingersite.com driver.get("https:/"); } @After public void tearDown() { driver.quit(); } }
In order to check the layout, we need to use LayoutReport class and instantiate a layoutReport object and assign it to Galen.checkout(param1, param2, param3). Here Galen.checkout function has three parameters:
param1 = webdriver instance (it is our driver object)
param2 = .gspec file
param3 = it is a tag for a specific layout
LayoutReport layoutReport = Galen.checkLayout(driver, "specs/homepage.gspec", Arrays.asList("desktop”));
Above code will generate an HTML report based on homepage.gspec file. You can find this report under tartget/ directory and test code should be like that:
@Test public void homePageLayoutTest() throws IOException { //Create a layoutReport object //checkLayout function checks the layout and returns a LayoutReport object LayoutReport layoutReport = Galen.checkLayout(driver, "specs/homepage.gspec", Arrays.asList("desktop")); //Create a tests list List<GalenTestInfo> tests = new LinkedList<GalenTestInfo>(); //Create a GalenTestInfo object GalenTestInfo test = GalenTestInfo.fromString("homepage layout"); //Get layoutReport and assign to test object test.getReport().layout(layoutReport, "check homepage layout"); //Add test object to the tests list tests.add(test); //Create a htmlReportBuilder object HtmlReportBuilder htmlReportBuilder = new HtmlReportBuilder(); //Create a report under /target folder based on tests list htmlReportBuilder.build(tests, "target"); //If layoutReport has errors Assert Fail if (layoutReport.errors() > 0) { Assert.fail("Layout test failed"); } }
Now, you have to create a Galen Specification (.gspec) file under resources folder to describe your website’s layout and rules. If you want to do image comparison, you should also add baseline image under this folder. Under the “target” folder we will generate test reports.
Step-3: Write a Galen Spec File
This gspec (Galen Spec) fileis for firebrick-termite-918071.hostingersite.com’s home page and it consists of many controls and checks such as:
- Alignment control
- Image comparison
- Below check
- Above check
#Declaring objects with css and xpath locators @objects header css div.fusion-secondary-header sw-logo css .fusion-logo-link #Navigation links are multi-line object type. Thus, we add * at the end of its decleration. navigation-links-* xpath //ul[@id='menu-main']/li[not((contains(@id,'mobile-menu-item')))] nav-menu css div.fusion-secondary-main-menu follow-us-box xpath //div[contains(@class,'fusion-alert')][1] #Home Page Tag = Home Page = #This is for Desktop @on desktop #Header properties header: inside screen 0px top inside screen 0px left inside screen 0px right #Logo properties sw-logo: #31 px below the header below header 31px #Image comparison with %2 precision ratio image file sw-logo.png, error %5 #Each navigation links must be alligned horizontally to each other #itemName -> Current item and nextItem -> Next item @forEach [navigation-links-*] as itemName, next as nextItem ${itemName}: aligned horizontally all ${nextItem} #Navigation menu must be 20px above to the follow us allert box nav-menu: above follow-us-box 20px
@On Mening:
Quite often you need to declare different specs for different conditions (e.g. various devices like mobile, tablet, desktop etc.). You can specify tags in your spec file so that it is easier to manage your layout testing. You can wrap all your checks inside @on statement like this:
= Main section = @on mobile menu: height 300 px @on desktop menu: height 40 px
In case your specs apply to all of the tags you can express that by using * symbol:
= Main section = @on * menu: height 70px @on mobile login-button: width 100px
You can also combine multiple tags using comma-separated tag notation
= Main section = @on mobile, desktop menu: height 300 px
Image Comparison:
As for image comparison – it is applied differently. Instead of comparing the complete page screenshot you can choose which specific element you would like to compare. And for each image comparison you can tune the algorithm with different settings (e.g. color tolerance, error rate etc.) and custom image filters (e.g. blur, saturation, quantinize, denoise). If you want to know more you can watch the video where it is explained how to prepare individual image samples and configure the image comparison for elements with noise background.
Ref: https://www.youtube.com/watch?v=bheFQfEGR6U
Step-4: HTML Reporting
When you run the code,
1- If there is a image comparison error, it will highlight it as follows:
2- Also, when we click the “Showimage comparison” link, it shows the mismatches:
3- If there is a layout error, it will highlight it as shown below:
4- Also, we can see the elements heat-map as follows:
5- Successful HTML report will look like this:
Thanks.
-Can

I am working as SDET at sahibinden.com and currently dealing with Software Testing and Test Automation. I also post my articles to my blog: http://cyildirim.com
Good info
Thanks, @Nalini. :)
Güzel makale olmuş. Elinize sağlık :)
Can Yıldırım’a teşekkür ediyoruz. :)
Hi Nice article, I have one query
I am running script parallel through testng.xml
But HTML report is not generated for both browser which i have mentioned in xml
I haven’t tried layout testing in parallel Stephen. Maybe Can Yıldırım has knowledge of this. It is better to put some breakpoints and debug your project. Maybe you will get some insights.
HeatMap is not generating
It is Galen’s problem. Please open a ticket on Galen project.
Hi, Thanks for creating such a nice article, I have just cloned the code into my PC and tried to execute the tests and finally ended up with error, following is the error details, could you help me in resolving the issue
ReferenceError: “org” is not defined.
(; line 1)
at org.mozilla.javascript.NativeGlobal.constructError(NativeGlobal.java:597)
at org.mozilla.javascript.NativeGlobal.constructError(NativeGlobal.java:557)
at org.mozilla.javascript.ScriptRuntime.name(ScriptRuntime.java:1076)
at org.mozilla.javascript.gen.c2.call(:1)
at org.mozilla.javascript.gen.c2.exec()
at org.mozilla.javascript.Context.evaluateReader(Context.java:820)
at org.mozilla.javascript.Context.evaluateString(Context.java:784)
at com.galenframework.javascript.GalenJsExecutor.importClasses(GalenJsExecutor.java:85)
at com.galenframework.javascript.GalenJsExecutor.importAllMajorClasses(GalenJsExecutor.java:62)
at com.galenframework.javascript.GalenJsExecutor.(GalenJsExecutor.java:58)
at com.galenframework.speclang2.pagespec.PageSpecHandler.createGalenJsExecutor(PageSpecHandler.java:97)
at com.galenframework.speclang2.pagespec.PageSpecHandler.(PageSpecHandler.java:65)
at com.galenframework.speclang2.pagespec.PageSpecReader.read(PageSpecReader.java:59)
at com.galenframework.speclang2.pagespec.PageSpecReader.read(PageSpecReader.java:45)
at com.galenframework.api.Galen.checkLayout(Galen.java:68)
at com.galenframework.api.Galen.checkLayout(Galen.java:59)
at com.galenframework.api.Galen.checkLayout(Galen.java:155)
at com.galenframework.api.Galen.checkLayout(Galen.java:129)
at com.sample.test.screens.GalenFrameworkTest.checkLogoVisibleAndImageVerification(GalenFrameworkTest.java:64)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:86)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:643)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:820)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1128)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:129)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:112)
at org.testng.TestRunner.privateRun(TestRunner.java:782)
at org.testng.TestRunner.run(TestRunner.java:632)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:366)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:361)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:319)
at org.testng.SuiteRunner.run(SuiteRunner.java:268)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1244)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1169)
at org.testng.TestNG.run(TestNG.java:1064)
at com.intellij.rt.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:66)
at com.intellij.rt.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:109)
I need to re-create the error on my machine but now I am using MAC. I am not sure I can reproduce this error on my machine.
But I found this page: https://stackoverflow.com/questions/8982551/getting-java-io-ioexception-when-running-junit-test-case-in-eclipse-continued
It may be because of the old library. Please try to update the library versions in pom.xml and re-try.