Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test examples #658

Merged
merged 5 commits into from
Jan 10, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,13 @@ cache:
- "$HOME/cache"

before_install:
# Start xvfb with a specific resolution and pixel depth
- "/sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_99.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :99 -ac -screen 0 1280x1024x24"
- CACHE="${HOME}/cache" CMAKE_VERSION=3.5.0 CMAKE_SHORT_VERSION=3.5 source ./scripts/install_cmake.sh
- npm prune

before_script:
- export DISPLAY=:99.0
- sh -e /etc/init.d/xvfb start

script:
- npm run build
Expand Down
26 changes: 25 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,16 @@ add_custom_target(
)
add_test(NAME get_data_files COMMAND "${CMAKE_COMMAND}" --build ${CMAKE_BINARY_DIR} --target data_files)

add_custom_command(OUTPUT "${GEOJS_DEPLOY_DIR}/examples/bundle.js"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
COMMAND npm run build-examples
COMMENT "Build examples"
VERBATIM
)
add_custom_target(examples DEPENDS "${GEOJS_DEPLOY_DIR}/examples/bundle.js")
add_test(NAME build_examples COMMAND "${CMAKE_COMMAND}" --build ${CMAKE_BINARY_DIR} --target examples)
set_property(TEST "build_examples" APPEND PROPERTY DEPENDS "get_data_files")

if(FFHEADLESS_TESTS)
find_program(NPM_EXECUTABLE npm)
add_test(
Expand All @@ -111,6 +121,16 @@ if(FFHEADLESS_TESTS)
set_property(TEST "total-coverage" APPEND PROPERTY DEPENDS "ffheadless")
set_property(TEST "ffheadless" APPEND PROPERTY DEPENDS "get_data_files")

add_test(
NAME "examplesheadless"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
COMMAND npm run examplesci
)
set_property(TEST "examplesheadless" APPEND PROPERTY ENVIRONMENT "CTEST_IMAGE_PATH=${CMAKE_CURRENT_BINARY_DIR}/images")
set_property(TEST "examplesheadless" APPEND PROPERTY ENVIRONMENT "TEST_SAVE_IMAGE=${TEST_SAVE_IMAGE}")
set_property(TEST "total-coverage" APPEND PROPERTY DEPENDS "examplesheadless")
set_property(TEST "examplesheadless" APPEND PROPERTY DEPENDS "build_examples")

configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/testing/test-runners/baseline_images.py"
"${CMAKE_CURRENT_BINARY_DIR}/test/baseline_images.py"
Expand All @@ -124,8 +144,12 @@ add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/base-images.tgz"
COMMAND "${CMAKE_COMMAND}" --build ${CMAKE_BINARY_DIR} --target data_files
# Run the ffheadless test, asking to save all images
COMMAND TEST_SAVE_IMAGE=all npm run ffci
# Build examples to make sure that they are available.
COMMAND npm run build-examples
# Run the examplesheadless test, asking to save all images
COMMAND TEST_SAVE_IMAGE=all npm run examplesci
# Make a tarball of all of the images
COMMAND tar -zcvf "${CMAKE_CURRENT_BINARY_DIR}/base-images.tgz" --exclude=*-test.png --exclude=*-diff.png --exclude=*-base.png -C "${CMAKE_CURRENT_BINARY_DIR}/images" .
COMMAND tar -zcvf "${CMAKE_CURRENT_BINARY_DIR}/base-images.tgz" --exclude=*-test.png --exclude=*-diff.png --exclude=*-base.png --exclude=*-screen.png -C "${CMAKE_CURRENT_BINARY_DIR}/images" .
COMMENT "Create baseline images, then tar them into a single file"
VERBATIM
)
Expand Down
6 changes: 6 additions & 0 deletions docs/developers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,12 @@ test command or set this parameter in CMake.
build correctly. Try running ``ccmake /path/to/geojs`` for a full
list of configuration options.

Examples should be tested by creating an entry in the ``tests/example-cases/``
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

directory. To run these tests in a normal browser, run
``npm run start`` and browse to `<http://localhost:9876/debug.html?test=all>`_.
Since the browser's direct screen output is used, the browser must be running
on the same machine as the ``npm run start`` command.

Selenium testing
----------------

Expand Down
1 change: 1 addition & 0 deletions docs/provisioning.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ convenience in configuring CMake options) ::
sudo apt-get install --yes \
cmake \
firefox \
imagemagick \
git \
libjpeg8-dev \
libpango1.0-dev \
Expand Down
1 change: 1 addition & 0 deletions examples/common/css/examples.css
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ html, body {
#map {
width: 100%;
height: calc(100% - 60px);
overflow: hidden;
}
4 changes: 4 additions & 0 deletions examples/lines/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ $(function () {
* the line.
*/
function show_lines(rawdata) {
$('#map').removeClass('ready');
if (!rawdata) {
return;
}
Expand All @@ -143,6 +144,9 @@ $(function () {
lineFeature.draw();
var text = 'Shown: ' + segments;
$('#lines-shown').text(text).attr('title', text);
map.onIdle(function () {
$('#map').addClass('ready');
});
}

/**
Expand Down
165 changes: 109 additions & 56 deletions karma-base.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,29 @@ function saveImage(name, image, always) {
}
}

/* Use ImageMagick's import tool to get a portion of the screen. The caller is
* responsible for identifying the useful portion of the screen.
*
* @param {string} name: base name for the image.
* @param {number} left: left screen coordinate
* @param {number} top: top screen coordinate
* @param {number} width: width in pixels of area to fetch.
* @param {number} height: height in pixels of area to fetch.
* @returns: a base64-encoded image.
*/
function getScreenImage(name, left, top, width, height) {
var child_process = require('child_process');
var dest = path.resolve(image_path, name + '-screen.png');
child_process.execSync(
'import -window root ' +
'-crop ' + width + 'x' + height + (left >= 0 ? '+' : '') + left +
(top >= 0 ? '+' : '') + top + ' +repage ' +
'\'' + dest.replace(/'/g, "'\\''") + '\'');
var xvfbImage = new Buffer(fs.readFileSync(dest)).toString('base64');
xvfbImage = 'data:image/png;base64,' + xvfbImage;
return xvfbImage;
}

/* Compare an image to a base image. If it violates a threshold, save the
* image and a diff between it and the base image. Returns the resemble
* results.
Expand All @@ -64,17 +87,6 @@ function saveImage(name, image, always) {
* @param {function} callback: a function to call when complete.
*/
function compareImage(name, image, threshold, callback) {
/* Note, we could read the xvfb frame buffer using imageMagick, which would
* get the entire browser display, including it's window border, tabs, search
* bar, and non-canvas elements. It might be worth install a kiosk extension
* to FireFox (or use Chrome in Kiosk mode), and exclude the portions of the
* window that are used for Karma information.
var child_process = require('child_process');
var dest = path.resolve(image_path, name + '-xvfb.png');
child_process.execSync('import -window root \'' + dest.replace(/'/g, "'\\''") + '\'');
var xvfbImage = new Buffer(fs.readFileSync(dest)).toString('base64');
xvfbImage = 'data:image/png;base64,' + xvfbImage;
*/
var resemble = require('node-resemble');
var src = path.resolve('dist/data/base-images', name + '.png');
if (!fs.existsSync(src)) {
Expand Down Expand Up @@ -138,7 +150,13 @@ var notes_middleware = function (config) {
if (request.method === 'PUT') {
return getRawBody(request).then(function (body) {
var name = query.name;
var image = '' + body;
var image;
if (query.screen === 'true') {
image = getScreenImage(name, query.left, query.top,
query.width, query.height);
} else {
image = '' + body;
}
saveImage(name, image);
if (query.compare === 'true') {
compareImage(name, image, query.threshold, function (results) {
Expand All @@ -165,49 +183,84 @@ var notes_middleware = function (config) {
};
};

module.exports = {
autoWatch: false,
files: [
test_case,
{pattern: 'tests/data/**/*', included: false},
{pattern: 'tests/cases/**/*.js', included: false, served: false, watched: true},
{pattern: 'tests/gl-cases/**/*.js', included: false, served: false, watched: true},
{pattern: 'dist/data/**/*', included: false},
{pattern: 'dist/examples/**/*', included: false}
],
proxies: {
'/testdata/': '/base/tests/data/',
'/data/': '/base/dist/data/',
'/examples/': '/base/dist/examples/'
},
browsers: [
'PhantomJS'
],
browserNoActivityTimeout: 30000,
reporters: [
'progress',
'kjhtml'
],
middleware: [
'notes'
],
plugins: [
{'middleware:notes': ['factory', notes_middleware]},
'karma-*'
],
preprocessors: {},
frameworks: [
'jasmine', 'sinon'
],
webpack: {
cache: true,
devtool: 'inline-source-map',
module: {
loaders: webpack_config.module.loaders
},
resolve: webpack_config.resolve,
plugins: webpack_config.exposed_plugins
}
/**
* Express style middleware to handle REST requests for OSM tiles on the test
* server.
*/
var osmtiles_middleware = function (config) {
return function (request, response, next) {
var match = request.url.match(/.*http:\/\/[a-c]\.tile.openstreetmap.org\/([0-9]+\/[0-9]+\/[0-9]+.png)$/);
/* Serve tiles if they have been proxied */
if (match && request.method === 'GET') {
var imagePath = 'dist/data/tiles/' + match[1];
var img = new Buffer(fs.readFileSync(imagePath));
response.setHeader('Content-Type', 'image/png');
response.setHeader('Content-Length', img.length);
response.setHeader('Access-Control-Allow-Origin', '*');
response.writeHead(200);
return response.end(img);
}
next();
};
};

module.exports.preprocessors[test_case] = ['webpack', 'sourcemap'];
module.exports = function (config) {
var newConfig = {
autoWatch: false,
files: [
test_case,
{pattern: 'tests/data/**/*', included: false},
{pattern: 'tests/cases/**/*.js', included: false, served: false, watched: true},
{pattern: 'tests/gl-cases/**/*.js', included: false, served: false, watched: true},
{pattern: 'tests/example-cases/**/*.js', included: false, served: false, watched: true},
{pattern: 'dist/data/**/*', included: false},
{pattern: 'dist/examples/**/*', included: false}
],
proxies: {
'/testdata/': '/base/tests/data/',
'/data/': '/base/dist/data/',
'/examples/': '/base/dist/examples/'
},
browsers: [
'PhantomJS'
],
customLaunchers: {
FirefoxWithProxy: {
base: 'Firefox',
prefs: {
'network.proxy.type': 2,
'network.proxy.autoconfig_url': config.protocol + '//' + config.hostname + ':' + config.port + '/testdata/proxy-for-tests.pac'
}
}
},
browserNoActivityTimeout: 30000,
reporters: [
'progress',
'kjhtml'
],
middleware: [
'notes',
'osmtiles'
],
plugins: [
{'middleware:notes': ['factory', notes_middleware]},
{'middleware:osmtiles': ['factory', osmtiles_middleware]},
'karma-*'
],
preprocessors: {},
frameworks: [
'jasmine', 'sinon'
],
webpack: {
cache: true,
devtool: 'inline-source-map',
module: {
loaders: webpack_config.module.loaders
},
resolve: webpack_config.resolve,
plugins: webpack_config.exposed_plugins
}
};
newConfig.preprocessors[test_case] = ['webpack', 'sourcemap'];
return newConfig;
};
39 changes: 20 additions & 19 deletions karma-cov.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// with coverage support.

var path = require('path');
var karma_config = require('./karma-base');

/**
* Return URL friendly browser string
Expand All @@ -11,24 +10,26 @@ function browser(b) {
return b.toLowerCase().split(/[ /-]/)[0];
}

karma_config.reporters = ['progress', 'coverage'];
karma_config.coverageReporter = {
reporters: [
{type: 'html', dir: 'dist/coverage/', subdir: browser},
{type: 'cobertura', dir: 'dist/cobertura/', file: 'coverage.xml', subdir: browser},
{type: 'json', dir: 'dist/coverage/json/', subdir: browser},
{type: 'lcovonly', dir: 'lcov', subdir: browser},
{type: 'text'}
]
};
karma_config.webpack.module.preLoaders = [
{
test: /\.js$/,
include: path.resolve('src/'),
loader: 'istanbul-instrumenter'
}
];

module.exports = function (config) {
var karma_config = require('./karma-base')(config);

karma_config.reporters = ['progress', 'coverage'];
karma_config.coverageReporter = {
reporters: [
{type: 'html', dir: 'dist/coverage/', subdir: browser},
{type: 'cobertura', dir: 'dist/cobertura/', file: 'coverage.xml', subdir: browser},
{type: 'json', dir: 'dist/coverage/json/', subdir: browser},
{type: 'lcovonly', dir: 'lcov', subdir: browser},
{type: 'text'}
]
};
karma_config.webpack.module.preLoaders = [
{
test: /\.js$/,
include: path.resolve('src/'),
loader: 'istanbul-instrumenter'
}
];

config.set(karma_config);
};
4 changes: 1 addition & 3 deletions karma.conf.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
var karma_config = require('./karma-base');

module.exports = function (config) {
config.set(karma_config);
config.set(require('./karma-base')(config));
};
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"express": "^4.13.4",
"file-loader": "^0.8.5",
"forever": "^0.15.2",
"fs-extra": "^1.0.0",
"gl-mat3": "^1.0.0",
"gl-mat4": "^1.1.4",
"gl-vec2": "^1.0.0",
Expand All @@ -61,7 +62,6 @@
"karma-sourcemap-loader": "^0.3.7",
"karma-webpack": "^1.7.0",
"mousetrap": "^1.6.0",
"node-fs-extra": "^0.8.1",
"node-resemble": "^1.1.3",
"phantomjs-prebuilt": "^2.1.5",
"proj4": "^2.3.14",
Expand All @@ -82,7 +82,9 @@
"start": "karma start karma.conf.js",
"ci": "GEOJS_TEST_CASE=tests/test-unit.js karma start karma-cov.conf.js --single-run --browsers PhantomJS",
"ffci": "GEOJS_TEST_CASE=tests/test-gl.js karma start karma-cov.conf.js --single-run --browsers Firefox",
"examplesci": "GEOJS_TEST_CASE=tests/test-examples.js karma start karma-cov.conf.js --single-run --browsers FirefoxWithProxy",
"test-webgl": "GEOJS_TEST_CASE=tests/test-gl.js xvfb-run -s '-ac -screen 0 1280x1024x24' karma start karma-cov.conf.js --single-run --browsers Firefox",
"test-examples": "GEOJS_TEST_CASE=tests/test-examples.js xvfb-run -s '-ac -screen 0 1280x1024x24' karma start karma-cov.conf.js --single-run --browsers FirefoxWithProxy",
"codecov": "cat lcov/*/lcov.info | codecov",
"combine-coverage": "istanbul-combine -d dist/cobertura -r cobertura 'dist/coverage/json/**/coverage-final.json'",
"examples": "webpack-dev-server --config webpack-examples.config.js --host ${HOST-127.0.0.1} --port ${PORT-8082} --content-base dist/",
Expand Down
2 changes: 1 addition & 1 deletion testing/test-data/base-images.tgz.md5
Original file line number Diff line number Diff line change
@@ -1 +1 @@
5fc9100434a75382b93dc86db6a8c62e
914356846f8c541a813bb7e53efc6c57
2 changes: 1 addition & 1 deletion testing/test-data/base-images.tgz.url
Original file line number Diff line number Diff line change
@@ -1 +1 @@
https://data.kitware.com/api/v1/file/5858590d8d777f1e3428d5b0/download
https://data.kitware.com/api/v1/file/586d1ff18d777f05f44a5c75/download
2 changes: 1 addition & 1 deletion testing/test-data/tiles.tgz.md5
Original file line number Diff line number Diff line change
@@ -1 +1 @@
73d3e6e8800e5d82d5f668413379373a
910b4894cc906dc3762dc9e314fd4025
Loading