Merge pull request #8903 from tschaub/rendering-tests
Additional render tests
@@ -79,6 +79,7 @@
|
|||||||
"proj4": "2.5.0",
|
"proj4": "2.5.0",
|
||||||
"puppeteer": "^1.10.0",
|
"puppeteer": "^1.10.0",
|
||||||
"rollup": "0.67.0",
|
"rollup": "0.67.0",
|
||||||
|
"serve-static": "^1.13.2",
|
||||||
"sinon": "^6.0.0",
|
"sinon": "^6.0.0",
|
||||||
"typescript": "^3.1.0-dev.20180905",
|
"typescript": "^3.1.0-dev.20180905",
|
||||||
"uglifyjs-webpack-plugin": "^2.0.1",
|
"uglifyjs-webpack-plugin": "^2.0.1",
|
||||||
|
|||||||
|
After Width: | Height: | Size: 44 KiB |
@@ -0,0 +1,22 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<style>
|
||||||
|
html, body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
#map {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="map"></div>
|
||||||
|
<script src="main.js"></script>
|
||||||
|
</body>
|
||||||
|
</script>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
import Map from '../../../src/ol/Map.js';
|
||||||
|
import View from '../../../src/ol/View.js';
|
||||||
|
import {Vector as VectorLayer, Tile as TileLayer} from '../../../src/ol/layer.js';
|
||||||
|
import {Vector as VectorSource, OSM} from '../../../src/ol/source.js';
|
||||||
|
import Point from '../../../src/ol/geom/Point.js';
|
||||||
|
import Feature from '../../../src/ol/Feature.js';
|
||||||
|
import {fromLonLat} from '../../../src/ol/proj.js';
|
||||||
|
import {Style, Icon} from '../../../src/ol/style.js';
|
||||||
|
|
||||||
|
const center = fromLonLat([8.6, 50.1]);
|
||||||
|
|
||||||
|
new Map({
|
||||||
|
layers: [
|
||||||
|
new TileLayer({
|
||||||
|
source: new OSM()
|
||||||
|
}),
|
||||||
|
new VectorLayer({
|
||||||
|
style: function() {
|
||||||
|
return new Style({
|
||||||
|
image: new Icon({
|
||||||
|
src: '/data/icon.png',
|
||||||
|
anchor: [0.5, 46],
|
||||||
|
anchorXUnits: 'fraction',
|
||||||
|
anchorYUnits: 'pixels'
|
||||||
|
})
|
||||||
|
});
|
||||||
|
},
|
||||||
|
source: new VectorSource({
|
||||||
|
features: [
|
||||||
|
new Feature(
|
||||||
|
new Point(center)
|
||||||
|
)
|
||||||
|
]
|
||||||
|
})
|
||||||
|
})
|
||||||
|
],
|
||||||
|
target: 'map',
|
||||||
|
view: new View({
|
||||||
|
center: center,
|
||||||
|
zoom: 3
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
render();
|
||||||
|
After Width: | Height: | Size: 13 KiB |
@@ -0,0 +1,22 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<style>
|
||||||
|
html, body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
#map {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="map"></div>
|
||||||
|
<script src="main.js"></script>
|
||||||
|
</body>
|
||||||
|
</script>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
import Map from '../../../src/ol/Map.js';
|
||||||
|
import View from '../../../src/ol/View.js';
|
||||||
|
import {Vector as VectorLayer, Tile as TileLayer} from '../../../src/ol/layer.js';
|
||||||
|
import {Vector as VectorSource, OSM} from '../../../src/ol/source.js';
|
||||||
|
import Point from '../../../src/ol/geom/Point.js';
|
||||||
|
import Feature from '../../../src/ol/Feature.js';
|
||||||
|
import {fromLonLat} from '../../../src/ol/proj.js';
|
||||||
|
|
||||||
|
const center = fromLonLat([-111, 45.7]);
|
||||||
|
|
||||||
|
new Map({
|
||||||
|
layers: [
|
||||||
|
new TileLayer({
|
||||||
|
source: new OSM()
|
||||||
|
}),
|
||||||
|
new VectorLayer({
|
||||||
|
source: new VectorSource({
|
||||||
|
features: [
|
||||||
|
new Feature(
|
||||||
|
new Point(center)
|
||||||
|
)
|
||||||
|
]
|
||||||
|
})
|
||||||
|
})
|
||||||
|
],
|
||||||
|
target: 'map',
|
||||||
|
view: new View({
|
||||||
|
center: center,
|
||||||
|
zoom: 4,
|
||||||
|
rotation: Math.PI / 4
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
render();
|
||||||
|
After Width: | Height: | Size: 2.5 KiB |
@@ -2,7 +2,7 @@
|
|||||||
const puppeteer = require('puppeteer');
|
const puppeteer = require('puppeteer');
|
||||||
const webpack = require('webpack');
|
const webpack = require('webpack');
|
||||||
const config = require('./webpack.config');
|
const config = require('./webpack.config');
|
||||||
const middleware = require('webpack-dev-middleware');
|
const webpackMiddleware = require('webpack-dev-middleware');
|
||||||
const http = require('http');
|
const http = require('http');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const png = require('pngjs');
|
const png = require('pngjs');
|
||||||
@@ -12,6 +12,7 @@ const pixelmatch = require('pixelmatch');
|
|||||||
const yargs = require('yargs');
|
const yargs = require('yargs');
|
||||||
const log = require('loglevelnext');
|
const log = require('loglevelnext');
|
||||||
const globby = require('globby');
|
const globby = require('globby');
|
||||||
|
const serveStatic = require('serve-static');
|
||||||
|
|
||||||
const compiler = webpack(Object.assign({mode: 'development'}, config));
|
const compiler = webpack(Object.assign({mode: 'development'}, config));
|
||||||
|
|
||||||
@@ -19,14 +20,10 @@ function getHref(entry) {
|
|||||||
return path.dirname(entry).slice(1) + '/';
|
return path.dirname(entry).slice(1) + '/';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const staticHandler = serveStatic(__dirname);
|
||||||
|
|
||||||
function notFound(req, res) {
|
function notFound(req, res) {
|
||||||
return () => {
|
return () => {
|
||||||
if (req.url === '/favicon.ico') {
|
|
||||||
res.writeHead(204);
|
|
||||||
res.end();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const items = [];
|
const items = [];
|
||||||
for (const key in config.entry) {
|
for (const key in config.entry) {
|
||||||
const href = getHref(config.entry[key]);
|
const href = getHref(config.entry[key]);
|
||||||
@@ -42,7 +39,7 @@ function notFound(req, res) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function serve(options) {
|
function serve(options) {
|
||||||
const handler = middleware(compiler, {
|
const webpackHandler = webpackMiddleware(compiler, {
|
||||||
lazy: true,
|
lazy: true,
|
||||||
logger: options.log,
|
logger: options.log,
|
||||||
stats: 'minimal'
|
stats: 'minimal'
|
||||||
@@ -50,7 +47,18 @@ function serve(options) {
|
|||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const server = http.createServer((req, res) => {
|
const server = http.createServer((req, res) => {
|
||||||
handler(req, res, notFound(req, res));
|
if (req.url === '/favicon.ico') {
|
||||||
|
res.writeHead(204);
|
||||||
|
res.end();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path.extname(req.url) === '.js') {
|
||||||
|
webpackHandler(req, res, notFound(req, res));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
staticHandler(req, res, notFound(req, res));
|
||||||
});
|
});
|
||||||
|
|
||||||
server.listen(options.port, options.host, err => {
|
server.listen(options.port, options.host, err => {
|
||||||
@@ -141,8 +149,10 @@ async function renderPage(page, entry, options) {
|
|||||||
resolve();
|
resolve();
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
options.log.debug('navigating', entry);
|
||||||
await page.goto(`http://${options.host}:${options.port}${getHref(entry)}`, {waitUntil: 'networkidle0'});
|
await page.goto(`http://${options.host}:${options.port}${getHref(entry)}`, {waitUntil: 'networkidle0'});
|
||||||
await renderCalled;
|
await renderCalled;
|
||||||
|
options.log.debug('screenshot', entry);
|
||||||
await page.screenshot({path: getActualScreenshotPath(entry)});
|
await page.screenshot({path: getActualScreenshotPath(entry)});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -168,7 +178,7 @@ async function renderEach(page, entries, options) {
|
|||||||
}
|
}
|
||||||
const error = await assertScreenshotsMatch(entry);
|
const error = await assertScreenshotsMatch(entry);
|
||||||
if (error) {
|
if (error) {
|
||||||
process.stderr.write(`${error.message}\n`);
|
options.log.error(error);
|
||||||
fail = true;
|
fail = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -181,7 +191,7 @@ async function renderEach(page, entries, options) {
|
|||||||
async function render(entries, options) {
|
async function render(entries, options) {
|
||||||
const browser = await puppeteer.launch({
|
const browser = await puppeteer.launch({
|
||||||
args: options.puppeteerArgs,
|
args: options.puppeteerArgs,
|
||||||
headless: !process.env.CI
|
headless: options.headless
|
||||||
});
|
});
|
||||||
|
|
||||||
let fail = false;
|
let fail = false;
|
||||||
@@ -232,14 +242,14 @@ async function getOutdated(entries, options) {
|
|||||||
for (const entry of entries) {
|
for (const entry of entries) {
|
||||||
const passPath = getPassFilePath(entry);
|
const passPath = getPassFilePath(entry);
|
||||||
const passTime = await getLatest(passPath);
|
const passTime = await getLatest(passPath);
|
||||||
options.log.debug(entry, 'pass time', passTime);
|
options.log.debug('pass time', entry, passTime);
|
||||||
if (passTime < libTime) {
|
if (passTime < libTime) {
|
||||||
outdated.push(entry);
|
outdated.push(entry);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const caseTime = await getLatest(path.join(__dirname, path.dirname(entry), '**', '*'));
|
const caseTime = await getLatest(path.join(__dirname, path.dirname(entry), '**', '*'));
|
||||||
options.log.debug(entry, 'case time', caseTime);
|
options.log.debug('case time', entry, caseTime);
|
||||||
if (passTime < caseTime) {
|
if (passTime < caseTime) {
|
||||||
outdated.push(entry);
|
outdated.push(entry);
|
||||||
continue;
|
continue;
|
||||||
@@ -254,7 +264,7 @@ async function main(entries, options) {
|
|||||||
if (!options.force) {
|
if (!options.force) {
|
||||||
entries = await getOutdated(entries, options);
|
entries = await getOutdated(entries, options);
|
||||||
}
|
}
|
||||||
if (entries.length === 0) {
|
if (!options.interactive && entries.length === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -304,8 +314,13 @@ if (require.main === module) {
|
|||||||
choices: ['trace', 'debug', 'info', 'warn', 'error', 'silent'],
|
choices: ['trace', 'debug', 'info', 'warn', 'error', 'silent'],
|
||||||
default: 'error'
|
default: 'error'
|
||||||
}).
|
}).
|
||||||
|
option('headless', {
|
||||||
|
describe: 'Launch Puppeteer in headless mode',
|
||||||
|
type: 'boolean',
|
||||||
|
default: process.env.CI ? false : true
|
||||||
|
}).
|
||||||
option('puppeteer-args', {
|
option('puppeteer-args', {
|
||||||
describe: 'Args of for puppeteer.launch()',
|
describe: 'Additional args for Puppeteer',
|
||||||
type: 'array',
|
type: 'array',
|
||||||
default: process.env.CI ? ['--no-sandbox', '--disable-setuid-sandbox'] : []
|
default: process.env.CI ? ['--no-sandbox', '--disable-setuid-sandbox'] : []
|
||||||
}).
|
}).
|
||||||
@@ -313,9 +328,6 @@ if (require.main === module) {
|
|||||||
|
|
||||||
const entries = Object.keys(config.entry).map(key => config.entry[key]);
|
const entries = Object.keys(config.entry).map(key => config.entry[key]);
|
||||||
|
|
||||||
if (options.interactive) {
|
|
||||||
options.force = true;
|
|
||||||
}
|
|
||||||
options.log = log.create({name: 'rendering', level: options.logLevel});
|
options.log = log.create({name: 'rendering', level: options.logLevel});
|
||||||
|
|
||||||
main(entries, options).catch(err => {
|
main(entries, options).catch(err => {
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
const CopyPlugin = require('copy-webpack-plugin');
|
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
|
||||||
@@ -15,22 +14,5 @@ module.exports = {
|
|||||||
context: __dirname,
|
context: __dirname,
|
||||||
target: 'web',
|
target: 'web',
|
||||||
entry: entry,
|
entry: entry,
|
||||||
module: {
|
|
||||||
rules: [{
|
|
||||||
use: {
|
|
||||||
loader: 'buble-loader'
|
|
||||||
},
|
|
||||||
test: /\.js$/,
|
|
||||||
include: [
|
|
||||||
path.join(__dirname, '..', 'src')
|
|
||||||
]
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
plugins: [
|
|
||||||
new CopyPlugin([
|
|
||||||
{from: '../src/ol/ol.css', to: 'css'},
|
|
||||||
{from: 'cases/**/*.html'}
|
|
||||||
])
|
|
||||||
],
|
|
||||||
devtool: 'source-map'
|
devtool: 'source-map'
|
||||||
};
|
};
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 615 B |
|
Before Width: | Height: | Size: 639 B |
|
Before Width: | Height: | Size: 4.0 KiB |
@@ -127,14 +127,6 @@ describe('ol.rendering.layer.Tile', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('tests the canvas renderer', function(done) {
|
|
||||||
createMap('canvas');
|
|
||||||
waitForTiles([source1, source2], {}, function() {
|
|
||||||
expectResemble(map, 'rendering/ol/layer/expected/2-layers-canvas.png',
|
|
||||||
IMAGE_TOLERANCE, done);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
where('WebGL').it('tests the WebGL renderer', function(done) {
|
where('WebGL').it('tests the WebGL renderer', function(done) {
|
||||||
assertWebGL();
|
assertWebGL();
|
||||||
createMap('webgl');
|
createMap('webgl');
|
||||||
|
|||||||
@@ -98,14 +98,6 @@ describe('ol.rendering.Map', function() {
|
|||||||
|
|
||||||
describe('#rotate()', function() {
|
describe('#rotate()', function() {
|
||||||
|
|
||||||
it('tests the canvas renderer', function(done) {
|
|
||||||
createMap('canvas');
|
|
||||||
map.getView().setRotation(90);
|
|
||||||
map.getView().setCenter([10, 10]);
|
|
||||||
expectResemble(
|
|
||||||
map, 'rendering/ol/expected/rotate-canvas.png', 2.8, done);
|
|
||||||
});
|
|
||||||
|
|
||||||
where('WebGL').it('tests the WebGL renderer', function(done) {
|
where('WebGL').it('tests the WebGL renderer', function(done) {
|
||||||
assertWebGL();
|
assertWebGL();
|
||||||
createMap('webgl');
|
createMap('webgl');
|
||||||
@@ -118,14 +110,6 @@ describe('ol.rendering.Map', function() {
|
|||||||
|
|
||||||
describe('#zoom()', function() {
|
describe('#zoom()', function() {
|
||||||
|
|
||||||
it('tests the canvas renderer', function(done) {
|
|
||||||
createMap('canvas');
|
|
||||||
map.getView().setCenter([10, 10]);
|
|
||||||
map.getView().setResolution(2);
|
|
||||||
expectResemble(
|
|
||||||
map, 'rendering/ol/expected/zoom-canvas.png', IMAGE_TOLERANCE, done);
|
|
||||||
});
|
|
||||||
|
|
||||||
where('WebGL').it('tests the WebGL renderer', function(done) {
|
where('WebGL').it('tests the WebGL renderer', function(done) {
|
||||||
assertWebGL();
|
assertWebGL();
|
||||||
createMap('webgl');
|
createMap('webgl');
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 1.2 KiB |
@@ -66,14 +66,6 @@ describe('ol.rendering.style.Icon', function() {
|
|||||||
img.src = src;
|
img.src = src;
|
||||||
}
|
}
|
||||||
|
|
||||||
it('tests the canvas renderer', function(done) {
|
|
||||||
createMap('canvas');
|
|
||||||
createFeatures('rendering/ol/data/icon.png', imgInfo, function() {
|
|
||||||
expectResemble(map, 'rendering/ol/style/expected/icon-canvas.png',
|
|
||||||
IMAGE_TOLERANCE, done);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('scales svg correctly in the canvas renderer', function(done) {
|
it('scales svg correctly in the canvas renderer', function(done) {
|
||||||
createMap('canvas', 512, 512);
|
createMap('canvas', 512, 512);
|
||||||
createFeatures('rendering/ol/data/me0.svg', {
|
createFeatures('rendering/ol/data/me0.svg', {
|
||||||
|
|||||||