Skip to content
This repository has been archived by the owner on Jul 3, 2019. It is now read-only.

Commit

Permalink
Browse files Browse the repository at this point in the history
Screenshots tools: frame capture and reporting.
  • Loading branch information
yurydelendik committed May 1, 2015
1 parent 603d707 commit 14ea5d0
Show file tree
Hide file tree
Showing 8 changed files with 734 additions and 0 deletions.
1 change: 1 addition & 0 deletions test/ats/.gitignore
@@ -1 +1,2 @@
swfs*
captures*
1 change: 1 addition & 0 deletions utils/.gitignore
Expand Up @@ -9,5 +9,6 @@ builder/
playerglobal-fp/
playerGlobal/
avm1tests/
pdiff/
*~

121 changes: 121 additions & 0 deletions utils/take_snapshots.js
@@ -0,0 +1,121 @@
/*
* Copyright 2015 Mozilla Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

var WebServer = require('../test/webserver.js').WebServer;
var WebBrowser = require('../test/webbrowser.js').WebBrowser;
var path = require('path');
var testutils = require('../test/testutils.js');

var server;
var host = 'localhost';

function startServer() {
server = new WebServer();
server.host = host;
server.port = options.port;
server.root = '.';
server.cacheExpirationTime = 3600;

var url = require('url'), fs = require('fs');
server.hooks['POST'].push(function (req, res) {
var parsedUrl = url.parse(req.url, true);
var pathname = parsedUrl.pathname;
if (!/^\/snapshots\/[\w\-_]+\/\d+$/.test(pathname)) {
return false;
}
var filename = 'build' + pathname + '.png';
testutils.ensureDirSync(path.dirname(filename));

var body = '';
req.on('data', function (data) {
body += data;
});
req.on('end', function () {
var i = body.indexOf('base64,');
var buffer = new Buffer(body.substring(i + 'base64,'.length), 'base64');
fs.writeFile(filename, buffer, function () {
res.writeHead(204, {'Content-Type': 'text/plain'});
res.end();
});
});

return true;
});

server.hooks['GET'].push(function (req, res) {
var parsedUrl = url.parse(req.url, true);
var pathname = parsedUrl.pathname;
if (pathname !== '/quit') {
return false;
}

console.log('Finishing');
server.stop();
browser.stop();
});

server.start();
}

function stopServer() {
server.stop();
}

var browser;

function normalizePath(s) {
return s[0] !== '/' ? '../../' + s : s;
}

function startBrowser() {
var listPath = normalizePath(options._[0]);

var startUrl = 'http://' + host + ':' + port +
'/utils/take_snapshots/index.html?list=' + listPath + '&frames=' + options.frames;
var browserPath = options.browser;
var name = path.basename(browserPath, path.extname(browserPath));
browser = WebBrowser.create({name: name, path: browserPath});
browser.start(startUrl);
}

function parseOptions() {
var yargs = require('yargs')
.usage('Usage: $0 <swfs-list>')
.demand(1)
.boolean(['help'])
.string(['manifestFile', 'browser', 'frames', 'port'])
.alias('browser', 'b').alias('help', 'h').alias('frames', 'f')
.describe('help', 'Show this help message')
.describe('browser', 'The path to a single browser ')
.demand('browser')
.describe('port', 'The port the HTTP server should listen on.')
.default('port', 8092)
.describe('frames', 'The frame(s) to take snapshots at.')
.default('frames', '1');

var result = yargs.argv;
if (result.help) {
yargs.showHelp();
process.exit(0);
}
return result;
}

var options = parseOptions();
port = options.port;

startServer();
startBrowser('/Gruntfile.js');
135 changes: 135 additions & 0 deletions utils/take_snapshots/driver.js
@@ -0,0 +1,135 @@
/*
* Copyright 2015 Mozilla Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

function parseQueryString(qs) {
if (!qs)
return {};

if (qs.charAt(0) == '?')
qs = qs.slice(1);

var values = qs.split('&');
var obj = {};
for (var i = 0; i < values.length; i++) {
var kv = values[i].split('=');
var key = kv[0], value = kv[1];
obj[decodeURIComponent(key)] = decodeURIComponent(value);
}

return obj;
}

var queryVariables = parseQueryString(window.location.search);

var easel, easelHost, player;

var list = queryVariables.list;
var frames = queryVariables.frames.split(',').map(function (x) { return x|0; });
var base = '../../';
var executionTimeout = 10000;

function runMovie(path, width, height, reportFrames, callback) {
function frameCallback() {
while (index < reportFrames.length && currentFrame >= reportFrames[index]) {
var snapshot = shumwayObj.takeScreenshot({stageContent: true, disableHidpi: true});
sendImage(reportFrames[index], snapshot.dataURL);
index++;
}
if (index >= reportFrames.length) {
terminate();
}
currentFrame++;
}

function terminate() {
if (terminated) {
return;
}

terminated = true;
document.getElementById('swfContainer').textContent = '';
shumwayObj.onFrame = null;
shumwayObj = null;
clearTimeout(timeout);

callback();
}

console.log('Running ' + path);
var div = document.createElement('div');
div.id = 'testswf';
document.getElementById('swfContainer').appendChild(div);

var timeout = setTimeout(function () {
terminate();
}, executionTimeout);
var terminated = false;

var currentFrame = -1, index = 0;
var shumwayObj;
shuobject.embedSWF(path, 'testswf', width, height, '9,0,10', null, {}, {salign: 'tl', scale: 'noscale'}, {}, function (e) {
shumwayObj = shuobject.getShumwayObject(e.ref);
shumwayObj.onFrame = frameCallback;
});
}

var swfsToProcess = [];
function readList() {
var xhr = new XMLHttpRequest();
xhr.open('GET', list, true);
xhr.onload = function () {
var content = xhr.responseText;
if (content) {
swfsToProcess = content.split(/\n/g).filter(function (line) {
return line && line[0] !== '#';
});
}
processNextSwf();
};
xhr.send();
}

var swfId;

function processNextSwf() {
if (swfsToProcess.length === 0) {
sendQuit();
return;
}
var swfPath = swfsToProcess.shift();
var i = swfPath.lastIndexOf('/'), j = swfPath.indexOf('.', i);
swfId = swfPath.substring(i + 1, j);
runMovie(base + swfPath, 1024, 1024, frames, function () {
processNextSwf();
});
}

function sendImage(n, dataURL) {
var xhr = new XMLHttpRequest();
xhr.open('POST', '/snapshots/' + swfId + '/' + n, true);
xhr.send(dataURL);
}

function sendQuit() {
var xhr = new XMLHttpRequest();
xhr.open('GET', '/quit', true);
xhr.onload = function () {
window.close();
};
xhr.send();
}

readList();
29 changes: 29 additions & 0 deletions utils/take_snapshots/index.html
@@ -0,0 +1,29 @@
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>SWF screenshots tool</title>
<style>
body {
background: #C0C0C0;
margin: 0;
}
#easelContainer {
width: 1024px;
height: 1024px;
}
.playerIFrame {
position: fixed;
width: 0px;
height: 0px;
right: 0px;
top: 0px;
}
</style>
<script src="../../build/shuobject/shuobject.js"></script>
<script src="driver.js"></script>
</head>
<body>
<div id="swfContainer"></div>
</body>
</html>
61 changes: 61 additions & 0 deletions utils/take_snapshots/report.html
@@ -0,0 +1,61 @@
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>Snapshot comparison report</title>
<script src="report.js"></script>
<style>
body {
font-family: sans-serif;
font-size: small;
}

table#report {
border: 1px solid #000000;
width: 220px;
}

table#report tr:nth-child(even) {
background: #C0C000;
}
table#report td:nth-child(2) {
text-align: center;
}

div#details {
position: fixed;
top: 10px;
bottom: 10px;
left: 250px;
right: 10px;
border: 1px solid #808080;
overflow: scroll;
}

span.wrapper {
display: inline-block;
padding: 2px;
}

span.fp {
color: white;
background-color: blue;
}

span.shumway {
color: white;
background-color: green;
}
</style>
</head>
<body>
<table id="report">
<tr>
<th>id</th><th>Success</th><th>Frames</th><th></th>
</tr>
</table>
<div id="details">

</div>
</body>
</html>

0 comments on commit 14ea5d0

Please sign in to comment.