ノノ
It's me ノノ small robot you know, friends of user interfaces.
Nono (ノノ), a fluent TypeScript API for triggering UI events. Helpful for testing front-ends.
Installation
npm install --save-dev interacto-nono
Usage
Some examples. More to come
import {robot} from 'interacto-nono';
robot(div)
.click();
robot()
.click(div);
robot("#mydiv")
.click();
robot()
.click({"target": canvas, "button": 1, "screenX": 111, "screenY": 222, "clientX": 11, "clientY": 22});
robot(canvas)
.pan(2, 10, "right", {}, 11);
robot(canvas)
.twoPan(1, 3, 10, "bottom");
robot(canvas)
.mousedown({"button": 0})
.mousemove({"button": 2})
.mousemove({"button": 0});
robot(canvas)
.click()
.click()
.mousemove()
.click()
.click();
robot(canvas)
.click()
.click()
.keydown({"code": "27"});
robot(canvas)
.click({"clientX": 11, "clientY": 23, "button": 1})
.click({"clientX": 11, "clientY": 23, "button": 1})
.mousemove({"clientX": 20, "clientY": 30, "button": 1})
.click({"clientX": 20, "clientY": 30, "button": 0})
.click({"clientX": 20, "clientY": 30, "button": 0});
robot(canvas)
.mousedown()
.mousemove()
.keydown({"code": "Escape"})
.mousedown()
.mousemove();
robot(text)
.keydown({"code": "a"})
.keyup({"code": "a"});
robot(canvas)
.mousedown()
.do(() => jest.runOnlyPendingTimers());
robot().input(checkbox);
robot().change(button);
robot().input(colorBox);
robot().change(comboBox);
robot().input(inputdate);
robot(aElement).input();
robot(spinner).input();
robot(textArea).input();
robot(canvas).scroll();
robot()
.wheel({"target": canvas, "button": 1, "screenX": 111, "screenY": 222, "clientX": 11, "clientY": 22,
"deltaX": 18, "deltaY": 19, "deltaZ": 20, "deltaMode": 21});
robot(elt)
.touchstart({}, [{"identifier": 1, "target": elt}])
.touchmove({}, [{"identifier": 1, "target": elt}])
.touchend({}, [{"identifier": 1, "target": elt}])
.touchstart({}, [{"identifier": 1, "target": elt}])
.touchmove({}, [{"identifier": 1, "target": elt}]);
robot(canvas)
.auxclick({"button": 2}, 2);
robot()
.click(canvas, 2)
.mousemove()
.keydown({"code": "27"});
robot(canvas)
.keepData()
.mousedown({"screenX": 1, "screenY": 2, "clientX": 11, "clientY": 23, "button": 0})
.mousemove({"screenX": 3, "screenY": 4, "clientX": 15, "clientY": 25})
.mouseup();
robot(text)
.keydown({"code": "A"})
.keepData()
.keydown({"code": "B"})
.keyup();
robot(elt)
.keepData()
.touchstart({}, [{"identifier": 1, "target": elt}])
.touchmove()
.touchend()
.touchstart()
.touchmove();
robot(c1)
.keepData()
.touchstart({}, [{"screenX": 3, "screenY": 20, "clientX": 150, "clientY": 200, "identifier": 3, "target": c1}])
.touchmove({}, [{"screenX": 16, "screenY": 21, "clientX": 160, "clientY": 201}])
.touchmove({}, [{"screenX": 20, "screenY": 25, "clientX": 200, "clientY": 205}])
.touchend({}, [{"screenX": 65, "screenY": 25, "clientX": 200, "clientY": 205}]);
Augmenting the API with own routines
You can take a look to module augmentation.
Or you can extend the Nono robot. An example for Jest
:
export interface JestNonoRobot {
runOnlyPendingTimers(): this;
runAllTimers(): this;
}
class JestNonoRobotImpl extends NonoRobotImpl implements JestNonoRobot {
public constructor(target?: EventTarget) {
super(target);
}
public runOnlyPendingTimers(): this {
jest.runOnlyPendingTimers();
return this;
}
public runAllTimers(): this {
jest.runAllTimers();
return this;
}
}
export function robot(target?: EventTarget): JestNonoRobot & NonoRobot {
return new JestNonoRobotImpl(target);
}
Using this robot we can now write:
robot(canvas)
.mousedown()
.runOnlyPendingTimers();