3

我有一个基本的 EXT JS 存储,它使用代理访问本地 json 文件。

例如

...
proxy: {
    type: 'ajax',
    api: {
        read: 'data/mydata.json'
    },
    reader: {
        type: 'json',
        root: 'datas',
        successProperty: 'success'
    }
} 
...

我想使用 Maven、Jasmine 和 PhantomJS 使用 Atlassian Bamboo(我的 CI 服务器)构建和测试我的项目。

当我在本地执行 PhantomJS 时,如下所示:

$ phantomjs "c:\phantomjs-1.6.1\examples\run-jasmine.js" run-tests.html

我得到以下输出:

'waitFor()' finished in 422ms.
 4 specs, 2 failures in 0.075s

这是因为 PhantomJS 无法使用EXT JS 代理的file://协议加载本地文件。

我正在关注这个示例,并且想知道是否可以模拟我的代理响应,以便我可以在本地(在我的 Bamboo 服务器上)使用 PhantomJS 和测试 html 文件,而不必将项目托管在像 Apache 这样的 Web 服务器中(我必须用 Maven 管理一个外部依赖项)。

如果没有,是否有任何其他机制(内置于 Jasmine、PhantomJS 或其他),我可以用来实现这一点?

4

3 回答 3

9

从文件系统加载时,实际上可以使用 PhantomJS 执行 XHR!

直接来自PhantomJs wiki

--web-security=[yes|no] disables web security and allows cross-domain XHR (default is yes)

另请参阅PhantomJs 的此问题报告,它可能会对该主题有所了解。

Sencha 的 'sencha create jsb' 命令使用 PhantomJs(Ext.Loader 使用 XHR),它支持从文件系统加载。

name: 'app-entry',
alias: 'a',
description: 'The file or URL path to your application\'s HTML entry point',

结帐[senchasdktools]/compat/command/src/modules/GenerateJSB.js[senchasdktools]/compat/command/scripts/phantomjs-jsb.js.

不过,我没有看到与上述web-security开关相关的任何内容。也许他们使用自定义 phantomJs 构建。

更新 此代码片段允许向文件系统发出 XHR 请求。用最新版本的 phantomJs (1.6.1/Windows) 测试:

var page = new WebPage();
page.settings.localToRemoteUrlAccessEnabled = true;

UPDATE2 这是一个工作示例。

将所有内容放在同一个文件夹中,添加一个test.txt包含一些内容的文件,然后运行

phantomjs script.js test.html

phantomjs 脚本(script.js):

var fs = require('fs');

var appLocation = phantom.args[0];

var page = new WebPage();

page.settings.localToRemoteUrlAccessEnabled = true;
page.settings.ignoreSslErrors = true;

page.onConsoleMessage = function(message, url, lineNumber) {
    console.log((url ? url + " " : "") + (lineNumber ? lineNumber + ": " : "") + message);
};

page.onError = function (msg, trace) {
    console.log(msg);
    trace.forEach(function(item) {
        console.log('  ', item.file, ':', item.line);
    });
    phantom.exit(1);
};

if (!/^file:\/\/|http(s?):\/\//.test(appLocation)) {
    appLocation = 'file:///' + fs.absolute(appLocation).replace(/\\/g, '/');
}

page.open(appLocation, function(status) {
    if (status !== 'success') {
        error("Failed opening: '" + appLocation + "'. Please verify that the URI is valid");
    }

    page.evaluate(function() {
        window.onerror = function(message, url, lineNumber) {
            console.log((url ? url + " " : "") + (lineNumber ? lineNumber + ": " : "") + message);
        };

    });

    timer = setInterval(function() {
        console.log('Timeout!');
        phantom.exit(1);
    }, 2000);
});

html文件(test.html):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html class="x-border-box x-strict">
<head>
    <title>Test</title>
    <script type="text/javascript">
    var xhr = new XMLHttpRequest();

    try {
        xhr.open('GET', 'test.txt', false);
        xhr.send(null);
    } catch (e) {
        console.log('cross origin?');
    }

    console.log('status', xhr.status);
    console.log('response', xhr.responseText);

    </script>
</head>
<body class="x-body">
</body>
</html>

Chrome 和 --disable-web-security 和 ExtJs

我实际上是--disable-web-security在开发过程中使用 Google Chrome 的启动参数来从文件系统运行我的 webapp,并且它在那里工作(启动 Chrome 时必须运行其他 Chrome 进程)。Chrome 将显示一条警告消息,指出您正在使用不受支持的选项(顶部的黄色通知栏)。

然而,为了让 Ext 在这样的设置中工作,我需要对 Ext.Connection 附加一个补丁来解决两个问题: (1) xhr.status 总是0在加载文件系统资源时出现。分机不将此状态代码视为successful. 当 Ext 在 PhantomJs 中运行时,有专门的代码来处理这个问题——这就是它应该在那里工作的原因。

(2) 当 URL 包含查询字符串时,Chrome 加载文件系统资源失败。在文件系统模式下,我覆盖 Connection 类以去除所有 url 参数。

于 2012-08-23T05:14:05.817 回答
4

即浏览器和 WebKit,限制(安全),除非您运行自己的网络服务器,否则无法绕过。nodejs 有很简单的方法。在本地机器的某个端口上运行服务器大约需要几行代码。

只需如下创建 server.js 并node server.js在运行 phantomjs 之前运行它

var http = require('http');
var fs=require('fs');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/html'});
  res.end(fs.readFileSync(__dirname + req.url, 'utf8')); 
}).listen(3000, '127.0.0.1');
console.log('Server running at http://127.0.0.1:3000/');

将此文件保存在项目根目录或更新行中

res.end(fs.readFileSync(__dirname + req.url, 'utf8')); 

__dirname 是 server.js 所在文件夹的路径,由节点进程设置....

现在您可以保留 data/*.json 甚至在节点中创建模拟数据;)

===更新====

在阅读了 PhantomJS 文档后,我发现你可以在没有 nodejs 的情况下做同样的事情。显然,PhanotmJS 包含所有上述模块

考虑检查:

你会很高兴去的。

于 2012-08-17T02:18:25.900 回答
1

I wrote 2 repos for dealing with ExtJS 4 for unit testing using Karma test runner/ Jasmine 1.x and 2.0 versions and dealing with Async Issues: here they are: https://github.com/cgauthier/karma_jasmine_1_extjs4 and https://github.com/cgauthier/karma_jasmine_2_extjs4.

于 2014-07-22T17:00:56.333 回答