2017-06-21 64 views
8

我們正在編寫離線第一個應用程序的基礎教程,並且使用JSDOM和Tape來測試我們的代碼。 在我們的代碼中,我們更新了DOM,以便通過將事件監聽器附加到窗口並監聽「在線」/「離線」事件,以及將文本節點從「在線」改爲「離線」,反之亦然,並且navigator.onLine將文本初始化爲在線/離線。像這樣:使用JSDOM模擬進行在線/離線

// 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脫機離線事件火災和我們的文本節點更新時說「離線」進行測試。

JSDOM有一個window.navigator.onLine財產,but it is read only,我們無法找到一種方法來改變它(總是爲真)。它似乎有online/offline events as well,但我看不到如何讓他們開火。

在節點測試時,我們如何模擬在線/離線?

回答

3

在JSDOM 11.0.0(這是我寫這個答案的當前版本)中沒有提供用於更改navigator.onLine或生成onlineoffline事件的規定。

但是,有可能接管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 
+0

這是非常相似,我終於實現了! 我們沒有使用Class或getter,而是用Object.defineProperty覆蓋它,並創建了我們自己的離線/在線事件。乾杯! –