Write integration tests (#719)

* Scaffold a simple test case for debugging

* Set up Jest environment that works with React

- Install and set up react-testing-library
- "Unignore" roughjs and browser-nativejs transformations
- Separate App component from ReactDOM

* Write first passing test

- Mock canvas
- Remove App file and mount/unmount ReactDOM on import

* Add tests for drag create behavior

* Fix comments in dragCreate

* Pin jest-mock-canvas dependency

* Remove dependency range for testing library

* Add tests for multi point mode and selection element

* Fix all tests due to decrease in updates to canvas when changing tools

* Disable state updates if component is unmounted

- Remove all event listeners
- Disable storing scene in state if component is unmounted

* Add tests for move and element selection

* Merge branch 'master' into add-integration-tests

* Add tests for resizing rectangle

* move unmounted check to syncActionResult method

* Use a custom test renderer instead of default testing-library functions

* Add custom query for selecting tools

* move files around

Co-authored-by: David Luzar <luzar.david@gmail.com>
This commit is contained in:
Gasim Gasimzada 2020-02-12 02:19:43 +04:00 committed by GitHub
parent ad4ad238ef
commit 7183234895
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 1180 additions and 5 deletions

View file

@ -475,6 +475,9 @@ export class App extends React.Component<any, AppState> {
res: ActionResult,
commitToHistory: boolean = true,
) => {
if (this.unmounted) {
return;
}
if (res.elements) {
elements = res.elements;
if (commitToHistory) {
@ -515,6 +518,11 @@ export class App extends React.Component<any, AppState> {
this.saveDebounced.flush();
};
private disableEvent: EventHandlerNonNull = e => {
e.preventDefault();
};
private unmounted = false;
public async componentDidMount() {
document.addEventListener("copy", this.onCopy);
document.addEventListener("paste", this.pasteFromClipboard);
@ -526,28 +534,32 @@ export class App extends React.Component<any, AppState> {
window.addEventListener("resize", this.onResize, false);
window.addEventListener("unload", this.onUnload, false);
window.addEventListener("blur", this.onUnload, false);
window.addEventListener("dragover", e => e.preventDefault(), false);
window.addEventListener("drop", e => e.preventDefault(), false);
window.addEventListener("dragover", this.disableEvent, false);
window.addEventListener("drop", this.disableEvent, false);
const searchParams = new URLSearchParams(window.location.search);
const id = searchParams.get("id");
if (id) {
// Backwards compatibility with legacy url format
this.syncActionResult(await loadScene(id));
const scene = await loadScene(id);
this.syncActionResult(scene);
} else {
const match = window.location.hash.match(
/^#json=([0-9]+),([a-zA-Z0-9_-]+)$/,
);
if (match) {
this.syncActionResult(await loadScene(match[1], match[2]));
const scene = await loadScene(match[1], match[2]);
this.syncActionResult(scene);
} else {
this.syncActionResult(await loadScene(null));
const scene = await loadScene(null);
this.syncActionResult(scene);
}
}
}
public componentWillUnmount() {
this.unmounted = true;
document.removeEventListener("copy", this.onCopy);
document.removeEventListener("paste", this.pasteFromClipboard);
document.removeEventListener("cut", this.onCut);
@ -558,9 +570,12 @@ export class App extends React.Component<any, AppState> {
this.updateCurrentCursorPosition,
false,
);
document.removeEventListener("keyup", this.onKeyUp);
window.removeEventListener("resize", this.onResize, false);
window.removeEventListener("unload", this.onUnload, false);
window.removeEventListener("blur", this.onUnload, false);
window.removeEventListener("dragover", this.disableEvent, false);
window.removeEventListener("drop", this.disableEvent, false);
}
public state: AppState = getDefaultAppState();