Skip to content

Commit

Permalink
Merge pull request #81 from drag-drop-touch-js/issue-77-resolution
Browse files Browse the repository at this point in the history
more tests, and --debug testing
  • Loading branch information
Bernardo-Castilho authored Aug 11, 2024
2 parents 5f618a7 + d2db467 commit 07edc6d
Show file tree
Hide file tree
Showing 14 changed files with 286 additions and 115 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,13 +166,15 @@ integration tests. Build testing consists of linting the source code using `tsc`
auto-formatting it using `prettier`, and compiling it into three bundles (debug, normal, and minified) using `esbuild`. Integration tests are found in the
`tests/touch.spec.js` file, using Playwright as test runner.

Additionally, `npm run test:debug` will run the tests with `DEBUG` statements preserved, useful for when tests fail to pass and you're trying to find out what's actually happening.

### Manual testing

To manually test in the browser, you can run `npm start` and then open the
URL that is printed to the console once the initial build tasks have finished.
This runs a local server that lets you run the demo page, but with the
`drag-drop-touch.esm.min.js` replaced by a `drag-drop-touch.debug.esm.js`
instead, which preserves all debug statements used in the TypeScript source.
instead, which preserves all debug statements used in the TypeScript source.

To add your own debug statements, use the `DEBUG:` label followed by either
a normal statement, or multiple statements wrapped in a new block.
5 changes: 1 addition & 4 deletions demo/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,7 @@
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>DragDropTouch</title>
<script
src="../dist/drag-drop-touch.esm.min.js?autoload"
type="module"
></script>
<script src="../dist/drag-drop-touch.esm.min.js?autoload" type="module"></script>
<script src="./index.js" type="module" async></script>
<link rel="stylesheet" href="./index.css" />
</head>
Expand Down
8 changes: 1 addition & 7 deletions demo/index.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
// Add a tiny touch simulator for CI testing
import { drag, tap } from "./touch-simulation.js";
globalThis.simulatedTouch = { drag, tap };

// The rest of the code doesn't know anything about touch
// events, it's written as normal drag-and-drop handlers.
let draggable = null;
let draggable = null;
const cols = document.querySelectorAll(`#columns .column`);

cols.forEach((col) => {
Expand Down
68 changes: 0 additions & 68 deletions demo/issue-77b/index.html

This file was deleted.

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@
"server": "node server.js",
"start": "npm run build && npm run server",
"test:integration": "playwright test tests --workers=1 --timeout 5000 --global-timeout 15000",
"test": "npm run start -- -- --test && rm -rf test-results"
"test": "npm run start -- -- --test && npm run test:cleanup",
"test:debug": "npm run start -- -- --test --debug && npm run test:cleanup",
"test:cleanup": "rm -rf test-results"
},
"repository": {
"type": "git",
Expand Down
15 changes: 10 additions & 5 deletions server.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ process.env.PORT = PORT;
const HOSTNAME = process.env.HOSTNAME ?? `localhost`;
process.env.HOSTNAME = HOSTNAME;

const testing = process.argv.includes(`--test`);
const debug = process.argv.includes(`--debug`);
const npm = process.platform === `win32` ? `npm.cmd` : `npm`;

// Set up the core server
Expand All @@ -25,7 +27,7 @@ app.use((req, res, next) => {

app.set("etag", false);
app.use((req, res, next) => {
if (!process.argv.includes(`--test`)) {
if (!testing || (testing && debug)) {
console.log(`[${new Date().toISOString()}] ${req.url}`);
}
next();
Expand All @@ -35,11 +37,14 @@ app.use((req, res, next) => {
app.use(`/`, (req, res, next) => {
const { url } = req;
if (url === `/`) {
if (testing) return res.redirect(`/tests/integration`);
return res.redirect(`/demo`);
}
const testing = process.argv.includes(`--test`);
if (url === `/dist/drag-drop-touch.esm.min.js?autoload` && !testing) {
return res.redirect(`/dist/drag-drop-touch.debug.esm.js?autoload`);
if (
url.includes(`/dist/drag-drop-touch.esm.min.js`) &&
(!testing || (testing && debug))
) {
return res.redirect(url.replace(`esm.min.js`, `debug.esm.js`));
}
next();
});
Expand All @@ -61,7 +66,7 @@ app.listen(PORT, () => {
console.log([``, line, mid, msg, mid, line, ``].join(`\n`));

// are we running tests?
if (process.argv.includes(`--test`)) {
if (testing) {
const runner = spawn(npm, [`run`, `test:integration`], {
stdio: `inherit`,
});
Expand Down
46 changes: 46 additions & 0 deletions tests/integration/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
[draggable] {
user-select: none;
}

.dragging {
opacity: 0.5;
}

#columns {
display: flex;
gap: 1rem;

.column {
display: inline-block;
height: 150px;
width: 150px;
background: lightgrey;
opacity: 1;

header {
color: #fff;
padding: 5px;
background: #222;
pointer-events: none;
}

&.over {
border: 2px dashed #000;
opacity: 0.5;
box-sizing: border-box;
}

& > input,
& > textarea,
& > select {
display: block;
width: 85%;
margin: 5%;
max-height: calc(1.25em * 4);
}

& > img {
height: 50%;
}
}
}
33 changes: 17 additions & 16 deletions demo/issue-77/index.html → tests/integration/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,31 @@
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Test file for issue 77</title>
<script type="module">
import { enableDragDropTouch } from "../../dist/drag-drop-touch.esm.min.js";
enableDragDropTouch(document, document, {
isPressHoldMode: true,
pressHoldThresholdPixels: 5,
});
</script>
<script src="../index.js" type="module" async></script>
<link rel="stylesheet" href="../index.css" />
<title>DragDropTouch</title>
<script
src="../../dist/drag-drop-touch.esm.min.js?autoload"
type="module"
></script>
<script src="./index.js" type="module" async></script>
<link rel="stylesheet" href="./index.css" />
</head>

<body>
<header>
<h1>Test page for issue 77</h1>
<p>
<a href="https://github.com/drag-drop-touch-js/dragdroptouch/issues/77"
>https://github.com/drag-drop-touch-js/dragdroptouch/issues/77</a
>
</p>
<h1>TEST</h1>
</header>

<main>
<section>
<header>
<h2>A box dragging example</h2>
<p>
Drag some boxes around with the mouse, then open your Developer
Tools, turn on mobile emulation, and try to do the same with touch
input enabled. Things should still work.
</p>
</header>

<div id="columns">
<div class="column" draggable="true">
<header>Input</header>
Expand Down
81 changes: 81 additions & 0 deletions tests/integration/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// Add a tiny touch simulator for CI testing
import * as simulatedTouch from "./touch-simulation.js";
globalThis.simulatedTouch = simulatedTouch;

let draggable = null;
const cols = document.querySelectorAll(`#columns .column`);

cols.forEach((col) => {
col.addEventListener(`dragstart`, handleDragStart);
col.addEventListener(`dragenter`, handleDragEnter);
col.addEventListener(`dragover`, handleDragOver);
col.addEventListener(`dragleave`, handleDragLeave);
col.addEventListener(`drop`, handleDrop);
col.addEventListener(`dragend`, handleDragEnd);
});

function handleDragStart({ target, dataTransfer }) {
if (target.className.includes(`column`)) {
draggable = target;
draggable.classList.add(`dragging`);

dataTransfer.effectAllowed = `move`;
dataTransfer.setData(`text`, draggable.innerHTML);

// customize drag image for one of the panels
const haveDragFn = dataTransfer.setDragImage instanceof Function;
if (haveDragFn && target.textContent.includes(`X`)) {
let img = new Image();
img.src = `dragimage.jpg`;
dataTransfer.setDragImage(img, img.width / 2, img.height / 2);
}
}
}

function handleDragOver(evt) {
if (draggable) {
evt.preventDefault();
evt.dataTransfer.dropEffect = `move`;
}
}

function handleDragEnter({ target }) {
if (draggable) {
target.classList.add(`over`);
}
}

function handleDragLeave({ target }) {
if (draggable) {
target.classList.remove(`over`);
}
}

function handleDragEnd() {
draggable = null;
cols.forEach((col) => col.classList.remove(`over`));
}

function handleDrop(evt) {
if (draggable === null) return;

evt.stopPropagation();
evt.stopImmediatePropagation();
evt.preventDefault();

if (draggable !== this) {
swapDom(draggable, this);
}
}

// https://stackoverflow.com/questions/9732624/how-to-swap-dom-child-nodes-in-javascript
function swapDom(a, b) {
let aParent = a.parentNode;
let bParent = b.parentNode;
let aHolder = document.createElement(`div`);
let bHolder = document.createElement(`div`);
aParent.replaceChild(aHolder, a);
bParent.replaceChild(bHolder, b);
aParent.replaceChild(b, aHolder);
bParent.replaceChild(a, bHolder);
}
32 changes: 32 additions & 0 deletions tests/integration/issue-77b/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<!doctype html>
<html>
<head>
<script type="module" src="./test.js"></script>
</head>

<body>
<p>window A</p>

<p>
<a id="from" draggable="true">
<svg>
<rect width="300" height="200" style="cursor: pointer; fill: green" />
<text
x="50%"
y="50%"
dy=".3em"
text-anchor="middle"
fill="white"
style="font: bold 20px sans-serif"
>
testing
</text>
</svg>
</a>
</p>

<p id="to">window B</p>

<p id="result"></p>
</body>
</html>
23 changes: 23 additions & 0 deletions tests/integration/issue-77b/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { enableDragDropTouch } from "../../../dist/drag-drop-touch.esm.min.js";

import * as simulatedTouch from "../touch-simulation.js";
globalThis.simulatedTouch = simulatedTouch;

globalThis.enablePressHold = (threshold = 0) => {
enableDragDropTouch(document, document, {
isPressHoldMode: true,
pressHoldThresholdPixels: threshold,
});
};

document.addEventListener(`dragover`, (e) => e.preventDefault());

document.addEventListener(`drop`, (e) => {
e.preventDefault();
document.getElementById(`result`).textContent =
e.dataTransfer.getData(`text/plain`);
});

document.addEventListener(`dragstart`, (e) =>
e.dataTransfer.setData(`text/plain`, `we dragged a ${e.target.tagName}`)
);
Loading

0 comments on commit 07edc6d

Please sign in to comment.