Testing Your Alfresco
Add-ons
Michael Suzuki
Software Engineer
Testing Your Alfresco Add-ons
•
•
•
•
•
Introduction
Automation Tools
Best Practice
Setting Up With Maven
Demo
Michael Suzuki
Will Abson
@suzukimichael @wabson
github.com/michaelsuzukisagi github.com/wabson
Why Testing Makes Sense
It builds Confidence that the systems is
behaving as it should.
• Validates no regression bugs have been
introduced
• Pins the functionality
• Helps find problems early
• Detecting difference
Test Types
• Unit Tests
• Integration Tests
• Functional Tests
The Right Balance
Unit Testing in the UI
• This has been hard until now!
• Aikau provides a framework for developing
AMD modules (widgets) on top of Share
• Testing is built-in using Grunt, Intern.io,
Node, NPM
Unit Testing – How it Works
• Intern.io provides testing framework
• Static JSON model defines the widgets to
be tested inside a page
• Bootstrap webscript supplied by Share to
take the test data in the body of a POST
request
Decoupling Widgets
• Tests use pub/sub framework to drive
widgets and capture behaviour
• Special logging widget
Alfresco/testing/SubscriptionLog to ensure the
correct data
• Tests can run separately from the
repository
• Widgets should use ‘services’ which provide
them with data, and which can be substituted
with mock data.
Code Coverage
• code-coverage NPM package allows us to
measure coverage
• Grunt tasks to instrument the Aikau code,
run test suites and gather the results
Running Unit Tests
• Different options for running the tests
• Local Selenium (typically used to write tests)
• Vagrant VM for local continuous background
testing
• Internal or external grids (e.g. SauceLabs)
More Information
• Declarative Configuration of Share – Dave
Draper / David Webster
• Dynamic UI Generation with Share and
Aikau – Kevin Dorr
• Unit Testing Aikau http://blogs.alfresco.com/wp/developer/20
14/02/26/unit-testing-aikau/
Testing Your Alfresco Add-ons
Automation Tools
WebDriver
An open source browser automation API.
Supports different OS, languages and browsers.
WebDriver Code
{
//Start fire fox
WebDriver driver = new FireFoxDriver();
//Navigate to share
driver.navigate(http://localhost:8080/share);
}
Locator Strategies
•
•
•
•
•
•
•
•
Id
Name
Tag name
Class name
CSS selector
Xpath
Link Text
Partial Link Text
Locator Strategies In Action
{
//By Id
WebElement username = driver.findElement(By.id(“iusername”));
//By Name
WebElement password = driver.findElement(By.name(“password”));
//By Tag Name
WebElement btn= driver.findElement(By.tagName(“button”));
//By CSS selector
username = driver.findElement(By.cssSelector(“input#iusername”));
//By class name
WebElement btn =driver.findElement(By.className(“button”));
//By xpath
btn = driver.findElement(By.cssSelector(“//button));
}
Interacting With Elements
{
//Find Element By Id
WebElement element = driver.findElement(By.id(“foo”));
//check if visible
element.isDisplayed();
//type in admin
element.sendKeys(“admin”);
//clear input field
element.clear();
//click action
element.click();
//get text
element.getText();
}
Testing Your Alfresco Add-ons
Best Practice
Always Use
• Page Object Pattern
• Render Pattern
Page Object
“A page object wraps an HTML page, or
fragment, with an application-specific API,
allowing you to manipulate page elements
without digging around in the HTML”
Martin Fowler
Login Page Object
public class LoginPage
{
private static By USERNAME_INPUT = By.id(“username");
private static By PASSWORD_INPUT = By.id(“password");
private static By SUBMIT_BUTTON = By.id(“submit");
public LoginPage(WebDriver driver) {}
public void login(String username, String password)
{
// Find By Id
WebElement username = driver.findElement(USERNAME_INPUT);
username.sendKeys(username);
WebElement password = driver.findElement(PASSWORD_INPUT);
password.sendKeys(password);
driver.findElement(SUBMIT_BUTTON).click();
}
}
Why You Should Use Page
Objects
• Encourages re-use of the code
• Makes tests more readable
• Encapsulates mechanical details of the
page
• Easier to maintain
Render Pattern
The logic which determines if a page has
rendered, by checking that all the
required web elements of the page, are
visible before it can be used.
Render Method In Action
public LoginPage render(RenderTime timer)
{
while (true)
{
timer.start();
try
{
if(driver.find(USERNAME_INPUT).isDisplayed() &&
driver.find(PASSWORD_INPUT).isDisplayed() &&
driver.find(SUBMIT_BUTTON).isDisplayed()
{
break;
}
}
catch (NoSuchElementException nse){}
finally
{
timer.end();
}
}
return this;
}
Share PO Project
Aims to mimic user interaction on Alfresco Share.
A library that is simple, reliable and reusable.
The project started in 2012 and is now part
of Alfresco core.
WebDrone Project
A Selenium WebDriver wrapper with added
functionality.
Provides additional tools:
• Selenium grid
• Image recognition
• Language support
Things To Avoid
• WebDriver code in test code
• Assertions in page objects
• Thread sleep
Testing Your Alfresco Add-ons
Demo
Build Add-ons with Maven
Setup Maven options
export MAVEN_OPTS="-XX:MaxPermSize=512m -Xmx1024m”
Create project from archetype
mvn archetype:generate DarchetypeCatalog=https://artifacts.alfresco.com/nexus/content/gr
oups/public/archetype-catalog.xml Dfilter=org.alfresco.maven.archetype:
Run AMP with Maven
mvn install -Pamp-to-war
Run test
mvn install –Pfunctional
Thank you
Additional Info
Share Page Object
https://github.com/Alfresco/community-edition/tree/master/projects/share-po
WebDrone
https://svn.alfresco.com/repos/alfresco-enterprise/benchmark/webdrone
Demo
https://github.com/michaelsuzukisagi/summit2014.git
Selenium WebDriver
http://docs.seleniumhq.org/docs/03_webdriver.jsp
https://code.google.com/p/selenium/wiki/PageObjects
Alfresco Maven
http://ecmarchitect.com/alfresco-developer-series-tutorials/maven-sdk/tutorial/tutorial.html
http://www.youtube.com/watch?v=Tu641nRGbtQ
Spring Loaded
https://github.com/spring-projects/spring-loaded
© Copyright 2026 Paperzz