2017-06-21 11 views
8

オフラインの最初のアプリの基本についてのチュートリアルを進めており、JSDOM with 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です。変更する方法が見つからない(常にtrue)。それはonline/offline events as wellを持っているようですが、私はそれらを発射する方法を見ることができません。

ノードでテストするときに、オンライン/オフラインになる方法をシミュレーションするにはどうすればよいですか?

答えて

3

navigator.onLineを変更するか、onlineofflineイベントを発生させるための(私はこの答えを書くように、現在のバージョンである)JSDOM 11.0.0での規定はありません。

しかし、それを制御してイベントを自分で生成するには、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

をこれは私がやってしまったものに非常によく似ています! クラスまたはゲッターを使用しませんでしたが、Object.definePropertyでオーバーライドし、独自のオフライン/オンラインイベントを作成しました。乾杯! –

関連する問題