UNPKG

pull2refresh

Version:
347 lines (288 loc) 14.6 kB
import { expect } from "chai"; import { DOMWindow, JSDOM, Options, VirtualConsole } from "jsdom"; import "mocha"; import { setTimeout } from "timers"; import PullToRefresh from "../../dist/pull2refresh"; describe("pull2refresh", () => { let dom: JSDOM; let window: DOMWindow; let document: Document; let onPullRatio: number | null; let onRefreshCalled: boolean; let p2r: PullToRefresh | null; beforeEach((done) => { onPullRatio = null; onRefreshCalled = false; p2r = null; const virtualConsole = new VirtualConsole().sendTo(console); const options: Options = { resources: "usable", runScripts: "dangerously", virtualConsole }; dom = new JSDOM(` <html> <body> <div class="content"> <div class="pulltorefresh" style="display: none; height: 35px;"> </div> <h1>Pull down to refresh</h1> <ul> <li>Item 1</li> <li>Item 2</li> <li>Item 3</li> </ul> </div> <script type="text/javascript" src="dist/pull2refresh.js"></script> <script> var p2r = new pull2refresh({ pullableElement: document.querySelector(".content"), refreshElement: document.querySelector(".pulltorefresh"), onRefresh: function() { window.onRefresh(); }, onPull: function(ratio) { window.onPull(ratio); } }); // Mock because jsdom cannot handle scrolling p2r.isScrollToTop = function() { return true; }; window.registerP2r(p2r); window.onLoaded(); </script> </body> </html> `, options); (global as any).window = window = dom.window; (global as any).document = document = dom.window.document; (dom.window as any).onLoaded = () => done(); (dom.window as any).onPull = (ratio: number) => onPullRatio = ratio; (dom.window as any).onRefresh = () => onRefreshCalled = true; (dom.window as any).registerP2r = (pullToRefresh: PullToRefresh) => p2r = pullToRefresh; }); it("should change display property for pulltorefresh element when initialized", () => { expect((document.querySelector(".pulltorefresh") as HTMLDivElement).style.display).to.be.equal("block"); }); it("should hide the pulltorefresh block when initialized", () => { // content is on top of the pulltorefresh expect((document.querySelector(".content") as HTMLDivElement).style.marginTop).to.be.equal("-35px"); }); it("should display the pulltorefresh block when pulling (mouse)", () => { const startScroll = getRandomInt(1, 100); const delta = 10; (document.querySelector(".content") as HTMLDivElement).dispatchEvent(mouseEvent(window, "mousedown", startScroll)); document.dispatchEvent(mouseEvent(window, "mousemove", startScroll + delta)); expect((document.querySelector(".content") as HTMLDivElement).style.marginTop).to.be.equal("-25px"); }); it("should display the pulltorefresh block when pulling (touch)", () => { const startScroll = getRandomInt(1, 100); const delta = 10; (document.querySelector(".content") as HTMLDivElement).dispatchEvent(touchEvent(window, "touchstart", startScroll)); document.dispatchEvent(touchEvent(window, "touchmove", startScroll + delta)); expect((document.querySelector(".content") as HTMLDivElement).style.marginTop).to.be.equal("-25px"); }); it("should call onPull callback when pulling (mouse)", () => { const startScroll = getRandomInt(1, 100); const delta = 7; (document.querySelector(".content") as HTMLDivElement).dispatchEvent(mouseEvent(window, "mousedown", startScroll)); document.dispatchEvent(mouseEvent(window, "mousemove", startScroll + delta)); expect(onPullRatio).to.be.equal(0.2); }); it("should call onPull callback when pulling (touch)", () => { const startScroll = getRandomInt(1, 100); const delta = 7; (document.querySelector(".content") as HTMLDivElement).dispatchEvent(touchEvent(window, "touchstart", startScroll)); document.dispatchEvent(touchEvent(window, "touchmove", startScroll + delta)); expect(onPullRatio).to.be.equal(0.2); }); it("should call onRefresh callback when pull is complete (mouse)", () => { const startScroll = getRandomInt(1, 100); const delta = 35; (document.querySelector(".content") as HTMLDivElement).dispatchEvent(mouseEvent(window, "mousedown", startScroll)); document.dispatchEvent(mouseEvent(window, "mousemove", startScroll + delta)); document.dispatchEvent(mouseEvent(window, "mouseup", startScroll + delta)); expect(onRefreshCalled).to.be.equal(true); }); it("should call onRefresh callback when pull is complete (touch)", () => { const startScroll = getRandomInt(1, 100); const delta = 35; (document.querySelector(".content") as HTMLDivElement).dispatchEvent(touchEvent(window, "touchstart", startScroll)); document.dispatchEvent(touchEvent(window, "touchmove", startScroll + delta)); document.dispatchEvent(touchEvent(window, "touchend", startScroll + delta)); expect(onRefreshCalled).to.be.equal(true); }); it("should not call onRefresh callback when pull is not complete (mouse)", () => { const startScroll = getRandomInt(1, 100); const delta = 30; (document.querySelector(".content") as HTMLDivElement).dispatchEvent(mouseEvent(window, "mousedown", startScroll)); document.dispatchEvent(mouseEvent(window, "mousemove", startScroll + delta)); document.dispatchEvent(mouseEvent(window, "mouseup", startScroll + delta)); expect(onRefreshCalled).to.be.equal(false); }); it("should not call onRefresh callback when pull is not complete (touch)", () => { const startScroll = getRandomInt(1, 100); const delta = 30; (document.querySelector(".content") as HTMLDivElement).dispatchEvent(touchEvent(window, "touchstart", startScroll)); document.dispatchEvent(touchEvent(window, "touchmove", startScroll + delta)); document.dispatchEvent(touchEvent(window, "touchend", startScroll + delta)); expect(onRefreshCalled).to.be.equal(false); }); it("should not be possible to pull again if done() wasn't called (mouse)", () => { const startScroll = getRandomInt(1, 100); const delta = 35; (document.querySelector(".content") as HTMLDivElement).dispatchEvent(mouseEvent(window, "mousedown", startScroll)); document.dispatchEvent(mouseEvent(window, "mousemove", startScroll + delta)); document.dispatchEvent(mouseEvent(window, "mouseup", startScroll + delta)); expect(onRefreshCalled).to.be.equal(true); // pull again onPullRatio = null; onRefreshCalled = false; (document.querySelector(".content") as HTMLDivElement).dispatchEvent(mouseEvent(window, "mousedown", startScroll)); document.dispatchEvent(mouseEvent(window, "mousemove", startScroll + delta)); document.dispatchEvent(mouseEvent(window, "mouseup", startScroll + delta)); expect(onPullRatio).to.be.equal(null); expect(onRefreshCalled).to.be.equal(false); }); it("should not be possible to pull again if done() wasn't called (touch)", () => { const startScroll = getRandomInt(1, 100); const delta = 35; (document.querySelector(".content") as HTMLDivElement).dispatchEvent(touchEvent(window, "touchstart", startScroll)); document.dispatchEvent(touchEvent(window, "touchmove", startScroll + delta)); document.dispatchEvent(touchEvent(window, "touchend", startScroll + delta)); expect(onRefreshCalled).to.be.equal(true); // pull again onPullRatio = null; onRefreshCalled = false; (document.querySelector(".content") as HTMLDivElement).dispatchEvent(touchEvent(window, "touchstart", startScroll)); document.dispatchEvent(touchEvent(window, "touchmove", startScroll + delta)); document.dispatchEvent(touchEvent(window, "touchend", startScroll + delta)); expect(onPullRatio).to.be.equal(null); expect(onRefreshCalled).to.be.equal(false); }); it("should be possible to pull again after done() called (mouse)", () => { const startScroll = getRandomInt(1, 100); const delta = 35; (document.querySelector(".content") as HTMLDivElement).dispatchEvent(mouseEvent(window, "mousedown", startScroll)); document.dispatchEvent(mouseEvent(window, "mousemove", startScroll + delta)); document.dispatchEvent(mouseEvent(window, "mouseup", startScroll + delta)); expect(onRefreshCalled).to.be.equal(true); // Call done() if (p2r) { p2r.done(); } // pull again onPullRatio = null; onRefreshCalled = false; (document.querySelector(".content") as HTMLDivElement).dispatchEvent(mouseEvent(window, "mousedown", startScroll)); document.dispatchEvent(mouseEvent(window, "mousemove", startScroll + delta)); document.dispatchEvent(mouseEvent(window, "mouseup", startScroll + delta)); expect(onPullRatio).to.be.equal(1); expect(onRefreshCalled).to.be.equal(true); }); it("should be possible to pull again after done() called (touch)", () => { const startScroll = getRandomInt(1, 100); const delta = 35; (document.querySelector(".content") as HTMLDivElement).dispatchEvent(touchEvent(window, "touchstart", startScroll)); document.dispatchEvent(touchEvent(window, "touchmove", startScroll + delta)); document.dispatchEvent(touchEvent(window, "touchend", startScroll + delta)); expect(onRefreshCalled).to.be.equal(true); // Call done() if (p2r) { p2r.done(); } // pull again onPullRatio = null; onRefreshCalled = false; (document.querySelector(".content") as HTMLDivElement).dispatchEvent(touchEvent(window, "touchstart", startScroll)); document.dispatchEvent(touchEvent(window, "touchmove", startScroll + delta)); document.dispatchEvent(touchEvent(window, "touchend", startScroll + delta)); expect(onPullRatio).to.be.equal(1); expect(onRefreshCalled).to.be.equal(true); }); it("should not hide the pulltorefresh block after pull ends (mouse)", () => { const startScroll = getRandomInt(1, 100); const delta = 35; (document.querySelector(".content") as HTMLDivElement).dispatchEvent(mouseEvent(window, "mousedown", startScroll)); document.dispatchEvent(mouseEvent(window, "mousemove", startScroll + delta)); document.dispatchEvent(mouseEvent(window, "mouseup", startScroll + delta)); expect((document.querySelector(".content") as HTMLDivElement).style.marginTop).to.be.equal("0px"); }); it("should not hide the pulltorefresh block after pull ends (touch)", () => { const startScroll = getRandomInt(1, 100); const delta = 35; (document.querySelector(".content") as HTMLDivElement).dispatchEvent(touchEvent(window, "touchstart", startScroll)); document.dispatchEvent(touchEvent(window, "touchmove", startScroll + delta)); document.dispatchEvent(touchEvent(window, "touchend", startScroll + delta)); expect((document.querySelector(".content") as HTMLDivElement).style.marginTop).to.be.equal("0px"); }); it("should hide the pulltorefresh block after pull ends and done() is called (mouse)", () => { const startScroll = getRandomInt(1, 100); const delta = 35; (document.querySelector(".content") as HTMLDivElement).dispatchEvent(mouseEvent(window, "mousedown", startScroll)); document.dispatchEvent(mouseEvent(window, "mousemove", startScroll + delta)); document.dispatchEvent(mouseEvent(window, "mouseup", startScroll + delta)); if (p2r) { p2r.done(); } expect((document.querySelector(".content") as HTMLDivElement).style.marginTop).to.be.equal("-35px"); }); it("should hide the pulltorefresh block after pull ends and done() is called (touch)", () => { const startScroll = getRandomInt(1, 100); const delta = 35; (document.querySelector(".content") as HTMLDivElement).dispatchEvent(touchEvent(window, "touchstart", startScroll)); document.dispatchEvent(touchEvent(window, "touchmove", startScroll + delta)); document.dispatchEvent(touchEvent(window, "touchend", startScroll + delta)); if (p2r) { p2r.done(); } expect((document.querySelector(".content") as HTMLDivElement).style.marginTop).to.be.equal("-35px"); }); it("should hide the pulltorefresh block when pull was not finished (mouse)", () => { const startScroll = getRandomInt(1, 100); const delta = 20; (document.querySelector(".content") as HTMLDivElement).dispatchEvent(mouseEvent(window, "mousedown", startScroll)); document.dispatchEvent(mouseEvent(window, "mousemove", startScroll + delta)); document.dispatchEvent(mouseEvent(window, "mouseup", startScroll + delta)); expect((document.querySelector(".content") as HTMLDivElement).style.marginTop).to.be.equal("-35px"); }); it("should hide the pulltorefresh block when pull was not finished (touch)", () => { const startScroll = getRandomInt(1, 100); const delta = 20; (document.querySelector(".content") as HTMLDivElement).dispatchEvent(touchEvent(window, "touchstart", startScroll)); document.dispatchEvent(touchEvent(window, "touchmove", startScroll + delta)); document.dispatchEvent(touchEvent(window, "touchend", startScroll + delta)); expect((document.querySelector(".content") as HTMLDivElement).style.marginTop).to.be.equal("-35px"); }); }); function getRandomInt(min: number, max: number): number { return Math.floor(Math.random() * (max - min + 1)) + min; } function mouseEvent(window: DOMWindow, event: string, y: number): MouseEvent { const mouse = new window.MouseEvent(event); (mouse as any).pageY = y; return mouse; } function touchEvent(window: DOMWindow, event: string, y: number): TouchEvent { const touch = new window.TouchEvent(event); touch.touches[0] = { clientX: 0, clientY: 0, identifier: 0, pageX: 0, pageY: 0, screenX: 0, screenY: 0, target: new window.EventTarget() }; touch.touches[1] = { clientX: 0, clientY: 0, identifier: 0, pageX: 0, pageY: y, screenX: 0, screenY: 0, target: new window.EventTarget() }; return touch; }