Skip to content

Commit

Permalink
feat(add-touch): begin implementation of touch helpers
Browse files Browse the repository at this point in the history
  • Loading branch information
dallaspersson committed Jan 11, 2018
1 parent 2662dd3 commit ee39595
Show file tree
Hide file tree
Showing 2 changed files with 133 additions and 6 deletions.
63 changes: 57 additions & 6 deletions src/acceptance.js
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,24 @@ function triggerMouseEvent(
exportedFunction,
selector,
options,
mouseEventsToTriggerFirst = []
eventsToTriggerFirst = []) {
triggerEvent(exportedFunction, selector, options, createMouseEvent, eventsToTriggerFirst)
}

function triggerTouchEvent(
exportedFunction,
selector,
options,
eventsToTriggerFirst = []) {
triggerEvent(exportedFunction, selector, options, createTouchEvent, eventsToTriggerFirst)
}

function triggerEvent(
exportedFunction,
selector,
options,
createEvent,
eventsToTriggerFirst = []
) {
const functionName = exportedFunction.name;
const eventName = functionName.toLowerCase();
Expand All @@ -184,19 +201,31 @@ function triggerMouseEvent(
? options()
: options;

function triggerMouseEvent(eventName) {
const event = createMouseEvent(eventName, evaluatedOptions);
function triggerEvent(eventName) {
const event = createEvent(eventName, evaluatedOptions);
jqueryElement[0].dispatchEvent(event);
}

const mouseEventsToTrigger = mouseEventsToTriggerFirst.concat([eventName]);
const eventsToTrigger = eventsToTriggerFirst.concat([eventName]);

mouseEventsToTrigger.forEach(eventName => {
triggerMouseEvent(eventName);
eventsToTrigger.forEach(eventName => {
triggerEvent(eventName);
});
});
}

/**
* Waits for an element to show up, and then simulates a user touch start by triggering a mouse event on that element.
* @param {string|jQuery} selector The jQuery selector or jQuery object to simulate touch start on.
* Note that the selector or jQuery object must represent exactly one (1) element in the app, or the call will fail.
* @param {object} [options] Any options to pass along to the simulated mouse event.
* @example
* mouseDown('.element-to-touch-start-on', {touches: [{ clientX: 1337, clientY: 1338 }]});
*/
export function touchStart(selector, options) {
triggerTouchEvent(touchStart, selector, options);
}

/**
* Waits for an input element to show up, and then simulates a user filling in the value of that input.
* @param {string|jQuery} selector The jQuery selector or jQuery object to fill in.
Expand Down Expand Up @@ -362,3 +391,25 @@ function createMouseEvent(

return result;
}

function createTouchEvent(
type,
{
touches = [{
clientX: 0,
clientY: 0,
}],
} = {}
) {
var result;

try {
result = new TouchEvent(type, {touches});
} catch (e) {
console.log(touches)
result = document.createEvent('TouchEvent');
result.initTouchEvent(type, {touches});
}

return result;
}
76 changes: 76 additions & 0 deletions tests/acceptance/touch-events.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import {touchStart, andThen, setupAsync, jQuery as $} from '../../src'

describe('Touch Events', () => {
describeMouseEventHelper(touchStart, 'touchstart');

function describeMouseEventHelper(func, eventName, extraTests = ()=> {}) {
describe(func.name, () => {
setupAsync();

let elementToInteractWith;

function attachElementToBody() {
document.body.appendChild(elementToInteractWith);
return elementToInteractWith;
}

beforeEach(() => {
elementToInteractWith = document.createElement('div');
elementToInteractWith.className = 'element-to-interact-with';
});

afterEach(() => {
document.body.removeChild(elementToInteractWith);
});

it(`triggers ${eventName} event on selected element`, () => {
attachElementToBody();
const spy = sinon.spy();
$(elementToInteractWith).on(eventName, spy);
func('.element-to-interact-with');
andThen(() => {
expect(spy).to.have.been.calledOnce();
});
});

it('waits until element shows up before trying to interact with it', () => {
const spy = sinon.spy();
$(elementToInteractWith).on(eventName, spy);
func('.element-to-interact-with');
andThen(() => {
expect(spy).to.have.been.calledOnce();
});

setTimeout(attachElementToBody, 500);
});

it('takes extra options as parameters', (done) => {
const element = attachElementToBody();
$(element).on(eventName, e => {
expect(e.touches[0].clientX).to.equal(1337);
expect(e.touches[0].clientY).to.equal(1338);
done();
});
func('.element-to-interact-with', {touches: [{ clientX: 1337, clientY: 1338 }]});
});

it('evaluates options lazily if passed as function', (done) => {
let screenX = 42;

andThen(() => {
screenX = 1337;
});

func('.element-to-interact-with', () => ({ screenX }));

const element = attachElementToBody();
$(element).on(eventName, e => {
expect(e.screenX).to.equal(1337);
done();
});
});

extraTests(attachElementToBody);
});
}
})

0 comments on commit ee39595

Please sign in to comment.