Publish Vulpes Preview 15 sources for desktop, Android and Tundra
Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
This commit is contained in:
parent
93e3a48004
commit
b38dea0597
25901 changed files with 9982925 additions and 369 deletions
291
gaia/apps/system/test/unit/app_statusbar_test.js
Executable file
291
gaia/apps/system/test/unit/app_statusbar_test.js
Executable file
|
|
@ -0,0 +1,291 @@
|
|||
/* global MockAppWindow, AppStatusbar, MocksHelper, MockTouchForwarder */
|
||||
'use strict';
|
||||
|
||||
require('/shared/test/unit/mocks/mock_l10n.js');
|
||||
requireApp('system/test/unit/mock_app_window.js');
|
||||
require('/test/unit/mock_touch_forwarder.js');
|
||||
requireApp('system/js/service.js');
|
||||
requireApp('system/js/base_ui.js');
|
||||
requireApp('system/js/app_statusbar.js');
|
||||
|
||||
var mocksForAppStatusbar = new MocksHelper([
|
||||
'AppWindow',
|
||||
'TouchForwarder'
|
||||
]).init();
|
||||
|
||||
suite('system/AppStatusbar', function() {
|
||||
mocksForAppStatusbar.attachTestHelpers();
|
||||
var app;
|
||||
var subject;
|
||||
setup(function() {
|
||||
this.sinon.useFakeTimers();
|
||||
app = new MockAppWindow({ chrome: { navigation: false }});
|
||||
subject = new AppStatusbar(app);
|
||||
this.sinon.stub(app, 'isFullScreen').returns(true);
|
||||
subject.screen = document.createElement('div');
|
||||
subject.chromeBar = document.createElement('div');
|
||||
subject.titleBar = document.createElement('div');
|
||||
});
|
||||
|
||||
suite('Reset destination if browser is destroyed', function() {
|
||||
test('Suspend', function() {
|
||||
app.element.dispatchEvent(new CustomEvent('_suspended'));
|
||||
assert.isNull(subject._touchForwarder.destination);
|
||||
});
|
||||
|
||||
test('Resume', function() {
|
||||
var newBrowserElement = document.createElement('iframe');
|
||||
app.browser = {
|
||||
element: newBrowserElement
|
||||
};
|
||||
app.element.dispatchEvent(new CustomEvent('_resumed'));
|
||||
assert.deepEqual(subject._touchForwarder.destination, newBrowserElement);
|
||||
});
|
||||
});
|
||||
|
||||
suite('fullscreen mode >', function() {
|
||||
function forgeTouchEvent(type, x, y) {
|
||||
var touch = document.createTouch(window, null, 42, x, y,
|
||||
x, y, x, y,
|
||||
0, 0, 0, 0);
|
||||
var touchList = document.createTouchList(touch);
|
||||
var touches = (type == 'touchstart' || type == 'touchmove') ?
|
||||
touchList : null;
|
||||
var changed = (type == 'touchmove') ?
|
||||
null : touchList;
|
||||
|
||||
var e = document.createEvent('TouchEvent');
|
||||
e.initTouchEvent(type, true, true,
|
||||
null, null, false, false, false, false,
|
||||
touches, null, changed);
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
function forgeMouseEvent(type, x, y) {
|
||||
var e = document.createEvent('MouseEvent');
|
||||
|
||||
e.initMouseEvent(type, true, true, window, 1, x, y, x, y,
|
||||
false, false, false, false, 0, null);
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
function fakeDispatch(type, x, y) {
|
||||
var e;
|
||||
if (type.startsWith('mouse')) {
|
||||
e = forgeMouseEvent(type, x, y);
|
||||
} else {
|
||||
e = forgeTouchEvent(type, x, y);
|
||||
}
|
||||
subject.handleStatusbarTouch(e, 24);
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
suite('Revealing the StatusBar >', function() {
|
||||
var transitionEndSpy;
|
||||
var element;
|
||||
setup(function() {
|
||||
element = subject.titleBar;
|
||||
transitionEndSpy = this.sinon.spy(element, 'addEventListener');
|
||||
});
|
||||
|
||||
function assertStatusBarReleased() {
|
||||
assert.isFalse(element.classList.contains('dragged'));
|
||||
}
|
||||
|
||||
function assertChromeBarDragging(isDragging) {
|
||||
assert.equal(subject.chromeBar.classList.contains('dragging'),
|
||||
isDragging);
|
||||
}
|
||||
|
||||
teardown(function() {
|
||||
this.sinon.clock.tick(10000);
|
||||
});
|
||||
|
||||
test('it should prevent default on mouse events',
|
||||
function() {
|
||||
var mousedown = fakeDispatch('mousedown', 100, 0);
|
||||
var mousemove = fakeDispatch('mousemove', 100, 2);
|
||||
var mouseup = fakeDispatch('mouseup', 100, 2);
|
||||
|
||||
assert.isTrue(mousedown.defaultPrevented);
|
||||
assert.isTrue(mousemove.defaultPrevented);
|
||||
assert.isTrue(mouseup.defaultPrevented);
|
||||
});
|
||||
|
||||
test('it should prevent default on all touch events to prevent reflows',
|
||||
function() {
|
||||
var touchstart = fakeDispatch('touchstart', 100, 0);
|
||||
var touchmove = fakeDispatch('touchmove', 100, 2);
|
||||
var touchend = fakeDispatch('touchend', 100, 2);
|
||||
|
||||
assert.isTrue(touchstart.defaultPrevented);
|
||||
assert.isTrue(touchmove.defaultPrevented);
|
||||
assert.isTrue(touchend.defaultPrevented);
|
||||
});
|
||||
|
||||
test('chromeBar dragging, then dragged then released when above ' +
|
||||
'threshold', function() {
|
||||
assertChromeBarDragging(false);
|
||||
fakeDispatch('touchstart', 100, 0);
|
||||
assertChromeBarDragging(true);
|
||||
fakeDispatch('touchmove', 100, 24);
|
||||
assertChromeBarDragging(true);
|
||||
fakeDispatch('touchend', 100, 25);
|
||||
assertChromeBarDragging(false);
|
||||
assert.isTrue(element.classList.contains('dragged'));
|
||||
});
|
||||
|
||||
test('chromeBar dragging then released when below threshold', function() {
|
||||
assertChromeBarDragging(false);
|
||||
fakeDispatch('touchstart', 100, 0);
|
||||
assertChromeBarDragging(true);
|
||||
fakeDispatch('touchmove', 100, 2);
|
||||
assertChromeBarDragging(true);
|
||||
fakeDispatch('touchend', 100, 2);
|
||||
assertChromeBarDragging(false);
|
||||
assertStatusBarReleased();
|
||||
});
|
||||
|
||||
test('it should stop the propagation of the events at first', function() {
|
||||
var fakeEvt = {
|
||||
stopImmediatePropagation: function() {},
|
||||
preventDefault: function() {},
|
||||
type: 'fake'
|
||||
};
|
||||
this.sinon.spy(fakeEvt, 'stopImmediatePropagation');
|
||||
subject.handleStatusbarTouch(fakeEvt, 24);
|
||||
sinon.assert.calledOnce(fakeEvt.stopImmediatePropagation);
|
||||
});
|
||||
|
||||
test('it should translate the statusbar on touchmove', function() {
|
||||
fakeDispatch('touchstart', 100, 0);
|
||||
fakeDispatch('touchmove', 100, 5);
|
||||
var transform = 'translateY(calc(5px - 100%))';
|
||||
assert.equal(element.style.transform, transform);
|
||||
fakeDispatch('touchend', 100, 5);
|
||||
});
|
||||
|
||||
test('it should set the dragged class on touchstart', function() {
|
||||
fakeDispatch('touchstart', 100, 0);
|
||||
assert.isFalse(element.classList.contains('dragged'));
|
||||
fakeDispatch('touchmove', 100, 24);
|
||||
fakeDispatch('touchend', 100, 25);
|
||||
assert.isTrue(element.classList.contains('dragged'));
|
||||
});
|
||||
|
||||
test('it should not translate the statusbar more than its height',
|
||||
function() {
|
||||
fakeDispatch('touchstart', 100, 0);
|
||||
fakeDispatch('touchmove', 100, 5);
|
||||
fakeDispatch('touchmove', 100, 15);
|
||||
var transform = 'translateY(calc(15px - 100%))';
|
||||
assert.equal(element.style.transform, transform);
|
||||
fakeDispatch('touchend', 100, 15);
|
||||
});
|
||||
|
||||
suite('after the gesture', function() {
|
||||
suite('when the StatusBar is not fully displayed', function() {
|
||||
setup(function() {
|
||||
fakeDispatch('touchstart', 100, 0);
|
||||
fakeDispatch('touchmove', 100, 5);
|
||||
fakeDispatch('touchend', 100, 5);
|
||||
});
|
||||
|
||||
test('it should hide it right away', function() {
|
||||
assertStatusBarReleased();
|
||||
});
|
||||
});
|
||||
|
||||
suite('when the StatusBar is fully displayed', function() {
|
||||
setup(function() {
|
||||
fakeDispatch('touchstart', 100, 0);
|
||||
fakeDispatch('touchmove', 100, 5);
|
||||
fakeDispatch('touchmove', 100, 24);
|
||||
fakeDispatch('touchend', 100, 24);
|
||||
});
|
||||
|
||||
test('it should not hide it right away', function() {
|
||||
assert.equal(subject.titleBar.style.transform, '');
|
||||
assert.equal(subject.titleBar.style.transition, '');
|
||||
assert.ok(subject.titleBar.classList.contains('dragged'));
|
||||
});
|
||||
|
||||
test('but after 5 seconds', function() {
|
||||
this.sinon.clock.tick(5000);
|
||||
assertStatusBarReleased();
|
||||
});
|
||||
|
||||
test('or if the utility tray hides', function() {
|
||||
window.dispatchEvent(new CustomEvent('utilitytraywillshow'));
|
||||
assertStatusBarReleased();
|
||||
});
|
||||
|
||||
test('or if the user interacts with the app', function() {
|
||||
// We're faking a touchstart event on the app iframe
|
||||
var iframe = app.browser.element;
|
||||
subject._touchForwarder.destination = window;
|
||||
|
||||
var e = forgeTouchEvent('touchstart', 100, 100);
|
||||
window.dispatchEvent(e);
|
||||
|
||||
assertStatusBarReleased();
|
||||
subject._touchForwarder.destination = iframe;
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('Touch forwarding in fullscreen >', function() {
|
||||
var forwardSpy;
|
||||
|
||||
setup(function() {
|
||||
forwardSpy = this.sinon.spy(MockTouchForwarder.prototype, 'forward');
|
||||
});
|
||||
|
||||
test('it should forward taps to the app', function() {
|
||||
var touchstart = fakeDispatch('touchstart', 100, 0);
|
||||
fakeDispatch('touchmove', 100, 2);
|
||||
var touchend = fakeDispatch('touchend', 100, 2);
|
||||
|
||||
assert.isTrue(forwardSpy.calledTwice);
|
||||
var call = forwardSpy.firstCall;
|
||||
assert.equal(call.args[0], touchstart);
|
||||
call = forwardSpy.getCall(1);
|
||||
assert.equal(call.args[0], touchend);
|
||||
});
|
||||
|
||||
suite('if it\'s not a tap and the statusbar is not fully displayed',
|
||||
function() {
|
||||
test('it should not forward any events', function() {
|
||||
fakeDispatch('touchstart', 100, 0);
|
||||
fakeDispatch('touchmove', 100, 8);
|
||||
fakeDispatch('touchend', 100, 8);
|
||||
|
||||
assert.isTrue(forwardSpy.notCalled);
|
||||
});
|
||||
});
|
||||
|
||||
test('it should forward touchmove once the statusbar is shown',
|
||||
function() {
|
||||
var touchstart = fakeDispatch('touchstart', 100, 0);
|
||||
fakeDispatch('touchmove', 100, 6);
|
||||
var secondMove = fakeDispatch('touchmove', 100, 26);
|
||||
var thirdMove = fakeDispatch('touchmove', 100, 28);
|
||||
var touchend = fakeDispatch('touchend', 100, 2);
|
||||
|
||||
assert.equal(forwardSpy.callCount, 4);
|
||||
var call = forwardSpy.firstCall;
|
||||
assert.equal(call.args[0], touchstart);
|
||||
call = forwardSpy.getCall(1);
|
||||
assert.equal(call.args[0], secondMove);
|
||||
call = forwardSpy.getCall(2);
|
||||
assert.equal(call.args[0], thirdMove);
|
||||
call = forwardSpy.getCall(3);
|
||||
assert.equal(call.args[0], touchend);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
Loading…
Reference in a new issue