Commit eb8731f7 authored by Colin PUY's avatar Colin PUY

add integration tests in community side

move fixtures in right folder

rearrange tests

update to protractor 2

update gitignore

update sp readme

integrations test in community side

remove duplicated tests in SP

back to protractor 1.3.1

change update-version script

fix README
parent 5b86d02a
......@@ -17,3 +17,4 @@ backend/webapp/src/test/resources/i18n/*.json
frontend/node/
frontend/build/
tests/node/
......@@ -7,11 +7,6 @@
<packaging>pom</packaging>
<modules>
<module>frontend</module>
<module>backend</module>
</modules>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- Properties encoding used by the maven compiler -->
......@@ -22,4 +17,18 @@
<npmVersion>2.1.7</npmVersion>
</properties>
<modules>
<module>frontend</module>
<module>backend</module>
</modules>
<profiles>
<profile>
<id>integration-test</id>
<modules>
<module>tests</module>
</modules>
</profile>
</profiles>
</project>
# Page Designer Tests
## Run tests
The module relies on Maven to run the app (the generated war in the `backend` directory), run the tests via npm and Protractor, and stop the app.
It uses the directories in `src/test/resources` as workspace, so if you add new pages in there, you can test them.
A profile `integration-test` has been created to launch the tests only on purpose.
mvn integration-test
The `pre-integration-test` phase will run the jar, the `integration-test` will test the pages with Protractor, and the `post-integration-phase` will stop the app.
### Alternative
By default mvn task will check for _ddescribe_ and _iit_ in spec files and fail if it find some. To avoid that in dev phase you can launch tests via gulp
gulp test
## Add a test
You can easily add a test by running the app as usual from the current directory :
java -jar ../backend/webapp/target/ui-designer-1.0.2-SNAPSHOT-standalone.jar -Drepository.pages=src/test/resources/pages/ -Drepository.fragments=src/test/resources/fragments/ -Drepository.widgets=./target/widgets
Once started, you can go to [your browser](http://localhost:8080/designer/) and add a new page.
The page is gonna be saved in `src/test/resources/pages` with a UUID.
For ease of use, you should rename the page to something simple, reflecting your use case (e.g. 'repeatLabelOverCollection.json').
Once that's done, you can add a new Protractor test in `src/test/javascript`, with the same naming convention (e.g. 'repeatLabelOverCollection.spec.js').
/* jshint node:true */
var gulp = require('gulp');
var ddescriber = require("../../community/frontend/gulp/ddescriber.js");
var protractor = require('gulp-protractor').protractor;
var connect = require('connect');
var multiparty = require('multiparty');
var http = require('http');
var proxy = require('http-proxy')
.createProxyServer({
target: {
host: 'localhost',
port: 8083
}
}).on('error', function (e) {
console.error(e);
});
/**
* Check for ddescribe and iit
*/
gulp.task('ddescriber', function () {
return gulp.src('src/test/**/*.spec.js')
.pipe(ddescriber());
});
gulp.task('test', function() {
var app = connect();
// use upload middleware to mock /API/formFileUpload
app.use(uploadMiddleware);
app.use(proxyMiddleware);
var server = http.createServer(app).listen(8086);
console.log('Server started http://localhost:8086');
return gulp.src(['src/test/**/*.spec.js'])
.pipe(protractor({
configFile: 'protractor.conf.js'
}))
.on('error', function (e) {
console.log(e);
throw e;
})
.on('end', function () {
console.log('close upload server');
server.close();
});
});
gulp.task('default', ['ddescriber'], function() {
gulp.start(['test']);
});
function matchUpload(req) {
return /API\/formFileUpload/.test(req.url);
}
function uploadMiddleware(req, res, next){
var form = new multiparty.Form();
var filename;
if( !matchUpload(req) ) {
next();
return;
}
form.on('error', function(error){
console.log('Error parsing form', error.stack);
res.writeHead(500, {'content-type': 'text/plain'});
res.end(JSON.stringify(error));
});
form.on('part', function(part){
if (part.filename) {
filename = part.filename;
}
part.resume();
});
form.on('close', function() {
res.statusCode = 200;
res.setHeader( 'content-type', 'text/html' );
res.write(JSON.stringify({
filename: filename,
tempPath: '1234.file'
}));
res.end();
});
form.parse(req);
}
/* proxyMiddleware forwards all requests to tomcat server
except fake upload request */
function proxyMiddleware(req, res, next) {
proxy.web(req, res);
}
{
"name": "tests",
"version": "0.0.1",
"description": "Bonitasoft tests",
"main": "index.js",
"engine": {
"npm": ">=2.0.0"
},
"devDependencies": {
"protractor": "~1.3.1",
"jasmine-reporters": "~1.0.1",
"gulp": "~3.8.8",
"gulp-protractor": "0.0.11"
},
"scripts": {
"pretest": "npm install && webdriver-manager update",
"test": "gulp ddescriber && gulp test"
},
"author": "",
"license": "proprietary",
"bugs": {
"url": "https://github.com/bonitasoft/bonita-form-builder/issues"
},
"homepage": "https://github.com/bonitasoft/bonita-form-builder",
"dependencies": {
"multiparty": "^4.1.2",
"connect": "^3.3.5",
"http-proxy": "^1.11.1"
}
}
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.bonitasoft.web</groupId>
<artifactId>ui-designer</artifactId>
<version>1.0.2-SNAPSHOT</version>
</parent>
<artifactId>ui-designer-tests</artifactId>
<packaging>pom</packaging>
<dependencies>
<!-- tell maven that ui-designer-backend has to be built -->
<dependency>
<groupId>org.bonitasoft.web</groupId>
<artifactId>ui-designer-backend-webapp</artifactId>
<version>${project.version}</version>
<classifier>exec-war</classifier>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<id>copy-test-files</id>
<phase>compile</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target name="copy test files in target">
<copy todir="${project.build.directory}">
<fileset dir="src/test/resources"/>
</copy>
</target>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.bazaarvoice.maven.plugins</groupId>
<artifactId>process-exec-maven-plugin</artifactId>
<version>0.7</version>
<executions>
<execution>
<id>ui-designer-process</id>
<phase>pre-integration-test</phase>
<goals>
<goal>start</goal>
</goals>
<configuration>
<name>UiDesigner</name>
<healthcheckUrl>http://localhost:8083/designer</healthcheckUrl>
<arguments>
<argument>java</argument>
<argument>-jar</argument>
<argument>
${basedir}/../backend/webapp/target/ui-designer-${project.version}-standalone.jar
</argument>
<argument>-Drepository.pages=${project.build.directory}/pages/</argument>
<argument>-Drepository.fragments=${project.build.directory}/fragments/</argument>
<argument>-Drepository.widgets=${project.build.directory}/widgets</argument>
<argument>-httpPort=8083</argument>
</arguments>
</configuration>
</execution>
<execution>
<id>stop-all</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop-all</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>0.0.19</version>
<executions>
<execution>
<id>install node and npm</id>
<goals>
<goal>install-node-and-npm</goal>
</goals>
<configuration>
<nodeVersion>v0.10.33</nodeVersion>
<npmVersion>2.1.7</npmVersion>
</configuration>
</execution>
<execution>
<id>npm test</id>
<goals>
<goal>npm</goal>
</goals>
<phase>integration-test</phase>
<configuration>
<arguments>run test</arguments>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
exports.config = {
// ---------------------------------------------------------------------------
// ----- How to setup Selenium -----------------------------------------------
// ---------------------------------------------------------------------------
//
// There are three ways to use the Selenium Server. Specify one of the
// following:
//
// 1. seleniumServerJar - to start a standalone Selenium Server locally.
// 2. seleniumAddress - to connect to a Selenium Server which is already
// running.
// 3. sauceUser/sauceKey - to use remote Selenium Servers via Sauce Labs.
//
// You can bypass a Selenium Server if you only want to test using Chrome.
// Set chromeOnly to true and ChromeDriver will be used directly (from the
// location specified in chromeDriver).
// The location of the standalone Selenium Server jar file, relative
// to the location of this config. If no other method of starting Selenium
// Server is found, this will default to
// node_modules/protractor/selenium/selenium-server...
seleniumServerJar: './node_modules/protractor/selenium/selenium-server-standalone-2.43.1.jar',
// The port to start the Selenium Server on, or null if the server should
// find its own unused port.
seleniumPort: null,
// Additional command line options to pass to selenium. For example,
// if you need to change the browser timeout, use
// seleniumArgs: ['-browserTimeout=60'],
seleniumArgs: [],
// ChromeDriver location is used to help the standalone Selenium Server
// find the chromedriver binary. This will be passed to the Selenium jar as
// the system property webdriver.chrome.driver. If null, Selenium will
// attempt to find ChromeDriver using PATH.
chromeDriver: './node_modules/protractor/selenium/chromedriver',
// If true, only ChromeDriver will be started, not a Selenium Server.
// Tests for browsers other than Chrome will not run.
chromeOnly: false,
// The address of a running Selenium Server. If specified, Protractor will
// connect to an already running instance of Selenium. This usually looks like
// seleniumAddress: 'http://localhost:4444/wd/hub'
seleniumAddress: null,
// If sauceUser and sauceKey are specified, seleniumServerJar will be ignored.
// The tests will be run remotely using Sauce Labs.
sauceUser: null,
sauceKey: null,
// Use sauceSeleniumAddress if you need to customize the URL Protractor
// uses to connect to sauce labs (for example, if you are tunneling selenium
// traffic through a sauce connect tunnel). Default is
// ondemand.saucelabs.com:80/wd/hub
sauceSeleniumAddress: null,
// ---------------------------------------------------------------------------
// ----- What tests to run ---------------------------------------------------
// ---------------------------------------------------------------------------
// Spec patterns are relative to the location of this config.
specs: [
'./src/test/spec/**/*.spec.js'
],
// Patterns to exclude.
exclude: [],
// Alternatively, suites may be used. When run without a command line
// property, all suites will run. If run with --suite=smoke or
// --suite=smoke,full only the patterns matched by the specified suites will
// run.
// suites: {
// smoke: 'spec/smoketests/*.js',
// full: 'spec/*.js'
//},
// ---------------------------------------------------------------------------
// ----- How to set up browsers ----------------------------------------------
// ---------------------------------------------------------------------------
//
// Protractor can launch your tests on one or more browsers. If you are
// testing on a single browser, use the capabilities option. If you are
// testing on multiple browsers, use the multiCapabilities array.
// For a list of available capabilities, see
// https://code.google.com/p/selenium/wiki/DesiredCapabilities
//
// In addition, you may specify count, shardTestFiles, and maxInstances.
capabilities: {
browserName: 'chrome',
// Number of times to run this set of capabilities (in parallel, unless
// limited by maxSessions). Default is 1.
count: 1,
// If this is set to be true, specs will be sharded by file (i.e. all
// files to be run by this set of capabilities will run in parallel).
// Default is false.
shardTestFiles: false,
// Maximum number of browser instances that can run in parallel for this
// set of capabilities. This is only needed if shardTestFiles is true.
// Default is 1.
maxInstances: 1,
// This option allows to hide the warning "--ignore-certificate-errors" in chrome
chromeOptions: {
args: ['--test-type'],
prefs: {
'download': {
'prompt_for_download': false
},
},
}
// Additional spec files to be run on this capability only.
// specs: ['spec/chromeOnlySpec.js']
},
// If you would like to run more than one instance of WebDriver on the same
// tests, use multiCapabilities, which takes an array of capabilities.
// If this is specified, capabilities will be ignored.
multiCapabilities: [],
// Maximum number of total browser sessions to run. Tests are queued in
// sequence if number of browser sessions is limited by this property.
// Use a number less than 1 to denote unlimited. Default is unlimited.
maxSessions: -1,
// ---------------------------------------------------------------------------
// ----- Global test information ---------------------------------------------
// ---------------------------------------------------------------------------
//
// A base URL for your application under test. Calls to protractor.get()
// with relative paths will be prepended with this.
baseUrl: 'http://localhost:8086',
// CSS Selector for the element housing the angular app - this defaults to
// body, but is necessary if ng-app is on a descendant of <body>.
rootElement: 'body',
// The timeout in milliseconds for each script run on the browser. This should
// be longer than the maximum time your application needs to stabilize between
// tasks.
allScriptsTimeout: 11000,
// How long to wait for a page to load.
getPageTimeout: 10000,
// A callback function called once tests are finished.
onComplete: function() {
// At this point, tests will be done but global objects will still be
// available.
},
// A callback function called once the tests have finished running and
// the WebDriver instance has been shut down. It is passed the exit code
// (0 if the tests passed or 1 if not). This is called once per capability.
onCleanUp: function(exitCode) {
},
// The params object will be passed directly to the Protractor instance,
// and can be accessed from your test as browser.params. It is an arbitrary
// object and can contain anything you may need in your test.
// This can be changed via the command line as:
// --params.login.user 'Joe'
params: {
//login: {
// user: 'Jane',
// password: '1234'
//}
},
// ---------------------------------------------------------------------------
// ----- The test framework --------------------------------------------------
// ---------------------------------------------------------------------------
// Test framework to use. This may be jasmine, cucumber, or mocha.
//
// Jasmine is fully supported as a test and assertion framework.
// Mocha and Cucumber have limited beta support. You will need to include your
// own assertion framework (such as Chai) if working with Mocha.
framework: 'jasmine',
// Options to be passed to Jasmine-node.
onPrepare: function() {
require('jasmine-reporters');
jasmine.getEnv().addReporter(
new jasmine.JUnitXmlReporter('target/reports/e2e-tests/')
);
},
// Options to be passed to minijasminenode.
//
// See the full list at https://github.com/juliemr/minijasminenode/tree/jasmine1
jasmineNodeOpts: {
// If true, display spec names.
isVerbose: false,
// If true, print colors to the terminal.
showColors: true,
// If true, include stack traces in failures.
includeStackTrace: true,
// Default time to wait in ms before a test fails.
defaultTimeoutInterval: 30000
},
// Options to be passed to Mocha.
//
// See the full list at http://visionmedia.github.io/mocha/
mochaOpts: {
ui: 'bdd',
reporter: 'list'
},
// Options to be passed to Cucumber.
cucumberOpts: {
// Require files before executing the features.
require: 'cucumber/stepDefinitions.js',
// Only execute the features or scenarios with tags matching @dev.
// This may be an array of strings to specify multiple tags to include.
tags: '@dev',
// How to format features (default: progress)
format: 'summary'
}
};
{
"designerVersion": "1.0.2-SNAPSHOT",
"id": "autocomplete",
"name": "autocomplete",
"lastUpdate": 1429799064124,
"rows": [
[{
"type": "container",
"dimension": {
"xs": 12,
"sm": 12,
"md": 12,
"lg": 12
},
"propertyValues": {
"cssClasses": {
"type": "constant",
"value": "test-simple"
},
"hidden": {
"type": "constant",
"value": false
},
"repeatedCollection": {
"type": "constant",
"value": ""
}
},
"reference": "a133b9d3-9a80-4b5b-bf7a-df5d99ea5928",
"rows": [
[{
"type": "component",
"dimension": {
"xs": 12,
"sm": 12,
"md": 12,
"lg": 12
},
"propertyValues": {
"cssClasses": {
"type": "constant",
"value": ""
},
"hidden": {
"type": "constant",
"value": false
},
"text": {
"type": "constant",
"value": "simple list of value"
},
"level": {
"type": "constant",
"value": "Level 3"
},
"alignment": {
"type": "constant",
"value": "left"
}
},
"reference": "9d70759c-48d9-4ea9-b9a1-988a16846606",
"id": "pbTitle"
}],
[{
"type": "component",
"id": "pbAutocomplete",
"dimension": {
"xs": 12,
"md": 12,
"sm": 12,
"lg": 12
},
"propertyValues": {
"cssClasses": {
"type": "constant",
"value": ""
},
"hidden": {
"type": "constant",
"value": false
},
"readOnly": {
"type": "constant",
"value": false
},
"labelHidden": {
"type": "constant",
"value": false
},
"label": {
"type": "constant",
"value": "city"
},
"labelPosition": {
"type": "constant",
"value": "left"
},
"labelWidth": {
"type": "constant",
"value": 4
},
"placeholder": {
"type": "constant"
},
"availableValues": {
"type": "constant",
"value": ["London", "Paris", "San Francisco"]
},
"value": {
"type": "data",
"value": "selectedCity"
},
"displayedKey": {
"type": "constant"
}
}
}],
[{
"type": "component",
"dimension": {
"xs": 12,
"sm": 12,
"md": 12,
"lg": 12
},
"propertyValues": {
"cssClasses": {
"type": "constant",
"value": ""
},
"hidden": {
"type": "constant",
"value": false
},
"text": {
"type": "constant",
"value": "city: {{selectedCity}}"
},
"alignment": {
"type": "constant",
"value": "left"
}
},
"reference": "3fb6cdc9-e085-49fe-bb3a-c4511e61e9ca",
"id": "pbText"
}]
]
}],
[{
"type": "container",
"dimension": {
"xs": 12,
"sm": 12,
"md": 12,
"lg": 12
},
"propertyValues": {
"cssClasses": {
"type": "constant",
"value": "test-object"
},
"hidden": {
"type": "constant",
"value": false
},
"repeatedCollection": {
"type": "constant",
"value": ""
}
},
"reference": "cf7059f9-6696-4751-80ac-c4710ce64bdd",
"rows": [
[{
"type": "component",
"dimension": {
"xs": 12,
"sm": 12,
"md": 12,
"lg": 12
},
"propertyValues": {
"cssClasses": {
"type": "constant",
"value": ""
},
"hidden": {
"type": "constant",
"value": false
},
"text": {
"type": "constant",