Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files

fixed some DOM manip async issues, references #32

  • Loading branch information...
Prinzhorn committed Jun 22, 2018
1 parent 9630dbc commit b007b4011ed090cf32435dc174e19f7f93fc4a27
@@ -2,6 +2,7 @@

* added observeMutations() method to behaviors (#22)
* conditions (responsive af)!
* fixed bugs regarding DOM manipulations (#32)

# 0.0.1

@@ -0,0 +1,55 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Scrollmeister</title>
<style>
body {
font-family: -apple-system,BlinkMacSystemFont,"Segoe UI","Roboto","Oxygen","Ubuntu","Cantarell","Fira Sans","Droid Sans","Helvetica Neue",sans-serif;
}
* {
margin: 0;
padding: 0;
}
h1 {
padding-bottom: 1em;
}
scroll-meister, element-meister {
display: block;
}
scroll-meister[fadein] {
opacity: 0;
transition: opacity 0.3s ease-in-out;
}
element-meister {
background: rgba(0, 255, 0, 0.5);
box-shadow: inset 0 0 0 1px rgba(255, 0, 0, 0.5);
}
element-meister.follower {
background: rgba(0, 0, 255, 0.5);
}
.cover > img {
width: 100%;
height: 100%;
object-fit: cover;
}
img {
display: block;
max-width: 100%;
}
</style>
</head>
<body>
<scroll-meister scroll guides-layout></scroll-meister>
<script src="../dist/scrollmeister-extras.js"></script>
</body>
</html>
@@ -0,0 +1,103 @@
const NUM_ITERATIONS = 100;
const NUM_BATCHES = 10;

describe('DOM fuzzing', () => {
beforeAll(async () => {
await page.exposeFunction('log', text => {
//console.log(text);
});
});

beforeEach(async () => {
await page.goto('http://localhost:4444/__tests__/dom-manipulation.test.html', {
waitUntil: 'domcontentloaded'
});
});

test(
'add / remove / shuffle all the things',
async () => {
await page.evaluate(
(NUM_ITERATIONS, NUM_BATCHES) => {
let wrapper = document.querySelector('scroll-meister');

let addElements = numElements => {
window.log(`addElements ${numElements}`);
while (numElements-- > 0) {
let element = document.createElement('element-meister');
element.textContent = Math.random();
element.setAttribute('layout', `height: ${numElements % 2 ? 'auto' : Math.random() * 1000 + 'px'};`);

if (Math.random() > 0.5) {
element.setAttribute('interpolate', 'y: top 0, bottom: 100;');
element.setAttribute('transform', '');
}

if (numElements % 2 === 0) {
wrapper.insertBefore(element, wrapper.children[Math.floor(Math.random() * wrapper.children.length)]);
} else {
wrapper.appendChild(element);
}
}
};

let removeElements = numElements => {
window.log(`removeElements ${numElements}`);
while (numElements > 0 && wrapper.children.length > 0) {
numElements--;
wrapper.removeChild(wrapper.children[Math.floor(Math.random() * wrapper.children.length)]);
}
};

let shuffleElements = () => {
window.log(`shuffleElements`);
for (let i = 0; i < wrapper.children.length; i++) {
wrapper.appendChild(wrapper.children[Math.floor(Math.random() * i)]);
}
};

let fuzzPromise = new Promise(resolve => {
let counter = 0;

let timer = setInterval(() => {
let operations = [];

for (let i = 0; i < NUM_BATCHES; i++) {
let rand = Math.random();

if (rand < 1 / 3) {
operations.push(addElements.bind(window, 1));
} else if (rand < 2 / 3) {
operations.push(removeElements.bind(window, 1));
} else {
operations.push(shuffleElements);
}
}

console.time('op');
for (let i = 0; i < operations.length; i++) {
let op = operations[i];
op();
}
console.timeEnd('op');

console.log(counter);

counter++;

if (counter >= NUM_ITERATIONS) {
clearInterval(timer);
resolve();
}
}, 1);
});

return fuzzPromise;
},
NUM_ITERATIONS,
NUM_BATCHES
);
},
30 * 60 * 1000
);
});
@@ -1,18 +1,56 @@
const firstLayout = async () => {
//Wait for Scrollmeister to do the first layout.
await page.evaluate(() => {
return new Promise(resolve => {
document.querySelector('scroll-meister').addEventListener('guides-layout:change', resolve, false);
});
});
};

describe('DOM manipulation', () => {
beforeAll(async () => {
await page.exposeFunction('log', text => {
console.log(text);
});
});

beforeEach(async () => {
await page.goto('http://localhost:4444/__tests__/dom-manipulation.test.html', {
waitUntil: 'domcontentloaded'
});
});

test('appendChild with flow elements', async () => {
await firstLayout();

//Wait for Scrollmeister to do the first layout.
await page.evaluate(() => {
return new Promise(resolve => {
document.querySelector('scroll-meister').addEventListener('guides-layout:change', resolve, false);
let wrapper = document.querySelector('scroll-meister');
let element = document.createElement('element-meister');
element.id = 'new';
element.setAttribute('layout', 'height: 100px;');

let promise = new Promise(resolve => {
element.addEventListener('layout:change', resolve, false);
});

wrapper.appendChild(element);

return promise;
});

let rects = await page.evaluate(() => {
let elements = document.querySelectorAll('element-meister');
return Array.from(elements).map(el => {
return el.getBoundingClientRect().y;
});
});

expect(rects).toEqual([0, 100, 200]);
});

test('insertBefore with flow elements', async () => {
await firstLayout();

await page.evaluate(() => {
let wrapper = document.querySelector('scroll-meister');
let element = document.createElement('element-meister');
@@ -37,4 +75,32 @@ describe('DOM manipulation', () => {

expect(rects).toEqual([0, 100, 200]);
});

test('appendChild with interpolate and transform behaviors', async () => {
await firstLayout();

await page.evaluate(() => {
let wrapper = document.querySelector('scroll-meister');
let element = document.createElement('element-meister');
element.id = 'new';
element.setAttribute('layout', 'height: 100px;');
element.setAttribute('interpolate', 'y: top 0, bottom: 100;');
element.setAttribute('transform', '');

let promise = new Promise(resolve => {
wrapper.addEventListener('guides-layout:change', resolve, false);
});

wrapper.appendChild(element);

return promise;
});

let y = await page.evaluate(() => {
let element = document.querySelector('#new');
return element.interpolate.values.y;
});

expect(y).toEqual(0);
});
});

0 comments on commit b007b40

Please sign in to comment.
You can’t perform that action at this time.