javascript - 使用 JSDOM 模拟上线/下线

标签 javascript node.js testing jsdom

我们正在编写有关离线第一个应用程序基础知识的教程,并使用带有 Tape 的 JSDOM 来测试我们的代码。 在我们的代码中,我们通过将事件监听器附加到窗口并监听“在线”/“离线”事件和 来更新 DOM,以便文本 Node 从“在线”变为“离线”,反之亦然navigator.onLine 将文本初始化为在线/离线。像这样:

// get the online status element from the DOM
var onlineStatusDom = document.querySelector('.online-status');
// navigator.onLine will be true when online and false when offline. We update the text in the online status element in the dom to reflect the online status from navigator.onLine
if (navigator.onLine) {
  onlineStatusDom.innerText = 'online';
} else {
  onlineStatusDom.innerText = 'offline';
}

// we use the 'online' and 'offline' events to update the online/offline notification to the user
// in IE8 the offline/online events exist on document.body rather than window, so make sure to reflect that in your code!
window.addEventListener('offline', function(e) {
  onlineStatusDom.innerText = 'offline';
});

window.addEventListener('online', function(e) {
  onlineStatusDom.innerText = 'online';
});

我们想使用 JSDOM 来测试当离线时触发离线事件并且我们的文本 Node 更新为“离线”。

JSDOM 有一个 window.navigator.onLine 属性,but it is read only ,而且我们找不到改变它的方法(总是如此)。它似乎有 online/offline events as well ,但我看不出如何让他们开火。

用node测试如何模拟上线/下线?

最佳答案

JSDOM 11.0.0(这是我写这个答案时的当前版本)没有规定更改 navigator.onLine 或生成 online离线事件。

但是,可以接管 navigator.onLine 来控制它并自己生成事件。这是一个概念证明:

const { JSDOM } = require("jsdom");
const { window } = new JSDOM();

class OnlineController {
    constructor(win) {
        this.win = win;
        this.onLine = win.navigator.onLine;

        // Replace the default onLine implementation with our own.
        Object.defineProperty(win.navigator.constructor.prototype,
                              "onLine",
                              {
                                  get: () => {
                                      return this.onLine;
                                  },
                              });
    }

    goOnline() {
        const was = this.onLine;
        this.onLine = true;

        // Fire only on transitions.
        if (!was) {
            this.fire("online");
        }
    }

    goOffline() {
        const was = this.onLine;
        this.onLine = false;

        // Fire only on transitions.
        if (was) {
            this.fire("offline");
        }
    }

    fire(event) {
        this.win.dispatchEvent(new this.win.Event(event));
    }
}

window.addEventListener("offline", function () {
    console.log("gone offline");
});

window.addEventListener("online", function () {
    console.log("gone online");
});

const cont = new OnlineController(window);
console.log("online?", window.navigator.onLine);
cont.goOffline();
console.log("online?", window.navigator.onLine);
cont.goOnline();
console.log("online?", window.navigator.onLine);

如果你运行这个文件,你应该得到:

online? true
gone offline
online? false
gone online
online? true

关于javascript - 使用 JSDOM 模拟上线/下线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44678841/

相关文章:

ruby - RSpec:每次指定对具有不同参数的方法的多次调用

ruby-on-rails - 在 View 中使用另一个模型导致测试错误

javascript - 依次运行多个 setIntervals

javascript - SVG TextPath 文本显示颠倒

ajax - 向本地主机nodejs服务器发送简单的ajax请求

mysql - 无法使用 NodeJS 建立与 MySQL 的连接

node.js - Cloudbees 上的 NodeJS v4 或 io.js

javascript - 我正在尝试使用 JavaScript 随机化 HTML 页面上的图像

javascript - 缺少回调时 `await promisify(setTimeout)(ms)` 是如何工作的?

android - 编辑在 robotium 中找不到的文本