使用 PhantomJS 网络服务器的 CasperJS 测试无法加载本地图像
CasperJS test with PhantomJS webserver fails to load local image
我有一个 CasperJS 测试套件需要验证图像加载事件。为了测试这个,我有一个 1x1 像素的 gif 图像,我使用 PhantomJS 网络服务器提供它:
var fs = require('fs');
var webserver = require('webserver');
casper.test.begin('Image onload should be invoked', 1, {
setUp: function() {
var server = webserver.create();
this.server = server.listen(8080, function(request, response) {
if (request.url == '/') {
response.writeHead(200, { 'Content-Type': 'text/html' });
response.write('' +
'<!doctype html>\n' +
'<html>\n' +
'<head>\n' +
'<script type="text/javascript">\n' +
'window.onload = function() {\n' +
'var px = document.createElement("img");\n' +
'px.onload = function() {\n' +
'window._pxLoad = true;\n' +
'};\n' +
'px.src = "px.gif";\n' +
'};\n' +
'</script>\n' +
'</head>\n' +
'<body></body>\n' +
'</html>' +
'');
} else if (request.url.match(/px\.gif$/i)) {
response.writeHead(200, {
'Content-Type': 'image/gif',
'Cache-Control': 'no-cache'
});
var filePath = fs.workingDirectory + request.url.split('/').join(fs.separator).replace(/\d/gi, '');
response.write(fs.read(filePath));
}
response.close();
});
},
tearDown: function() {
this.server.close();
},
test: function(test) {
casper.start('http://localhost:8080', function() {
this.waitFor(function() {
return this.evaluate(function () {
return window._pxLoad !== undefined;
});
}, function then() {
var flag = this.evaluate(function () {
return window._pxLoad;
});
test.assertTruthy(flag, 'Image has been successfully loaded');
});
});
casper.run(function () {
test.done();
});
}
});
此测试失败,因为 window._pxLoad !== undefined
未在 5000 毫秒超时内进行评估。我什至在图像处理程序中放置了 console.log
语句,它们表明我的路由有效,服务器确实收到了这个 /px.gif
调用,但看起来根本没有提供 git 图像。
我尝试将对本地 px.gif
的调用替换为来自互联网的类似图像 this one,并且测试通过!所以问题肯定与 PhantomJS 网络服务器如何提供本地 gif 图片有关。
好的,看来我自己找到了答案。好吧,有点。
首先,我无法让我的 PhantomJS 网络服务器解决方案工作。所以我创建了一个运行网络服务器的简单 Node.js 脚本。它在 运行 测试套件之前作为子进程产生:
img_server.js
var http = require('http');
var fs = require('fs');
var path = require('path');
var argv = process.argv;
var port = argv.length > 3 ? parseInt(argv[3], 10) || 8124;
http.createServer(function(req, res) {
var fileStream = fs.createReadStream(path.join(__dirname, 'px.gif'));
res.writeHead(200, {
'Content-Type': 'image/gif',
'Cache-Control': 'no-cache'
});
fileStream.pipe(res);
}).listen(port);
// This is important. Script should put something in the STDOUT when started.
// The CasperJS test suite will bind to this inside setUp hook to know when server is ready
console.log('Server running at http://127.0.0.1:' + port + '/');
对 CasperJS 测试套件的更改:
var fs = require('fs');
var webserver = require('webserver');
var process = require('child_process');
var spawn = process.spawn;
casper.test.setUp(function(done) {
this.imgServerChild = spawn('node', ['img_server.js', '-p', '8180']);
// This where STDOUT from server script is used
this.imgServerChild.stdout.on("data", done);
});
casper.test.tearDown(function() {
this.imgServerChild.kill('SIGKILL');
});
// The rest of test suite
当然,我还更改了伪造的 HTML 输出中图像文件的路径。现在图像是从不同的域提供的,这对我来说完全没问题。现在测试正在运行。
我有一个 CasperJS 测试套件需要验证图像加载事件。为了测试这个,我有一个 1x1 像素的 gif 图像,我使用 PhantomJS 网络服务器提供它:
var fs = require('fs');
var webserver = require('webserver');
casper.test.begin('Image onload should be invoked', 1, {
setUp: function() {
var server = webserver.create();
this.server = server.listen(8080, function(request, response) {
if (request.url == '/') {
response.writeHead(200, { 'Content-Type': 'text/html' });
response.write('' +
'<!doctype html>\n' +
'<html>\n' +
'<head>\n' +
'<script type="text/javascript">\n' +
'window.onload = function() {\n' +
'var px = document.createElement("img");\n' +
'px.onload = function() {\n' +
'window._pxLoad = true;\n' +
'};\n' +
'px.src = "px.gif";\n' +
'};\n' +
'</script>\n' +
'</head>\n' +
'<body></body>\n' +
'</html>' +
'');
} else if (request.url.match(/px\.gif$/i)) {
response.writeHead(200, {
'Content-Type': 'image/gif',
'Cache-Control': 'no-cache'
});
var filePath = fs.workingDirectory + request.url.split('/').join(fs.separator).replace(/\d/gi, '');
response.write(fs.read(filePath));
}
response.close();
});
},
tearDown: function() {
this.server.close();
},
test: function(test) {
casper.start('http://localhost:8080', function() {
this.waitFor(function() {
return this.evaluate(function () {
return window._pxLoad !== undefined;
});
}, function then() {
var flag = this.evaluate(function () {
return window._pxLoad;
});
test.assertTruthy(flag, 'Image has been successfully loaded');
});
});
casper.run(function () {
test.done();
});
}
});
此测试失败,因为 window._pxLoad !== undefined
未在 5000 毫秒超时内进行评估。我什至在图像处理程序中放置了 console.log
语句,它们表明我的路由有效,服务器确实收到了这个 /px.gif
调用,但看起来根本没有提供 git 图像。
我尝试将对本地 px.gif
的调用替换为来自互联网的类似图像 this one,并且测试通过!所以问题肯定与 PhantomJS 网络服务器如何提供本地 gif 图片有关。
好的,看来我自己找到了答案。好吧,有点。 首先,我无法让我的 PhantomJS 网络服务器解决方案工作。所以我创建了一个运行网络服务器的简单 Node.js 脚本。它在 运行 测试套件之前作为子进程产生:
img_server.js
var http = require('http');
var fs = require('fs');
var path = require('path');
var argv = process.argv;
var port = argv.length > 3 ? parseInt(argv[3], 10) || 8124;
http.createServer(function(req, res) {
var fileStream = fs.createReadStream(path.join(__dirname, 'px.gif'));
res.writeHead(200, {
'Content-Type': 'image/gif',
'Cache-Control': 'no-cache'
});
fileStream.pipe(res);
}).listen(port);
// This is important. Script should put something in the STDOUT when started.
// The CasperJS test suite will bind to this inside setUp hook to know when server is ready
console.log('Server running at http://127.0.0.1:' + port + '/');
对 CasperJS 测试套件的更改:
var fs = require('fs');
var webserver = require('webserver');
var process = require('child_process');
var spawn = process.spawn;
casper.test.setUp(function(done) {
this.imgServerChild = spawn('node', ['img_server.js', '-p', '8180']);
// This where STDOUT from server script is used
this.imgServerChild.stdout.on("data", done);
});
casper.test.tearDown(function() {
this.imgServerChild.kill('SIGKILL');
});
// The rest of test suite
当然,我还更改了伪造的 HTML 输出中图像文件的路径。现在图像是从不同的域提供的,这对我来说完全没问题。现在测试正在运行。