对同一个幻像实例使用两次 createPage()

Using createPage() twice for the same phantom instance

我正在尝试使用 PhantomJS 设置 mocha 测试,但我遇到了无法使用同一个 phantom 实例创建多个页面的问题。第一个测试用例运行良好,但第二个测试用例超时。我只想使用一个实例,因为它应该更快。

var assert = require('assert');
var phantom = require('phantom');
var path = require('path');

var ph;

describe('document', function() {
    before(function(done) { // Create only one phantom instance for the whole suite
        this.timeout(10000); // Prevent test case from aborting while phantom loads
        phantom.create(function(p) {
            ph = p;
            done();
        }, {
            dnodeOpts: {weak: false}
        });
    });

    it('should have a title', function(done) {
        ph.createPage(function(page) {
            var url = 'file:///' + path.resolve(__dirname + '/index.html');
            page.open(url, function(status) {
                page.evaluate(function() {
                    return document.title;
                }, function(title) {
                    assert.equal('This is a title', title);
                    ph.exit();
                    done();
                });
            });
        });
    });

    it('should have the same title', function(done) {
        ph.createPage(function(page) {
            var url = 'file:///' + path.resolve(__dirname + '/index.html');
            page.open(url, function(status) {
                page.evaluate(function() {
                    return document.title;
                }, function(title) {
                    assert.equal('This is a title', title);
                    ph.exit();
                    done();
                });
            });
        });
    });
});

为什么第二次打不开?

您在第一次测试后退出 PhantomJS,因此第二次测试失败。在所有测试之后,您只需要 运行 ph.exit(); 一次。我怀疑这可以通过以下方式完成:

describe('document', function() {
  before(...);
  after(function(done) {
    ph.exit();
    done();
  });
  it(...);
  it(...);
});

您甚至可以在 before 期间达到 createPage 并在测试中使用 page 实例。每个测试用例仍应打开一个新的 URL,以便呈现一个新的 DOM。这可能会更快,更能防止内存泄漏。

顺便说一句,PhantomJS' localStorage 永远不会被清除(因为它存储在磁盘上),所以你必须在每个测试用例之后或执行结束时自己清除它。
PhantomJS 每个进程也只有一个 CookieJar(仅在内存中),因此如果您测试登录或类似的东西,则必须删除 cookie。