Skip to content

Commit

Permalink
Fix a few more media element test
Browse files Browse the repository at this point in the history
  • Loading branch information
limzykenneth committed Dec 1, 2024
1 parent 095d497 commit ef31f7b
Show file tree
Hide file tree
Showing 2 changed files with 254 additions and 255 deletions.
271 changes: 16 additions & 255 deletions test/unit/dom/dom.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import p5 from '../../../src/app.js';
import { testSketchWithPromise } from '../../js/p5_helpers';

import { mockP5, mockP5Prototype } from '../../js/mocks';
Expand Down Expand Up @@ -319,7 +318,7 @@ suite('DOM', function() {

test('should return a p5.Element of div type', function() {
const testElement = mockP5Prototype.createDiv();
assert.instanceOf(testElement, p5.Element);
assert.instanceOf(testElement, Element);
assert.instanceOf(testElement.elt, HTMLDivElement);
});

Expand All @@ -341,7 +340,7 @@ suite('DOM', function() {

test('should return a p5.Element of p type', function() {
const testElement = mockP5Prototype.createP();
assert.instanceOf(testElement, p5.Element);
assert.instanceOf(testElement, Element);
assert.instanceOf(testElement.elt, HTMLParagraphElement);
});

Expand All @@ -363,7 +362,7 @@ suite('DOM', function() {

test('should return a p5.Element of span type', function() {
const testElement = mockP5Prototype.createSpan();
assert.instanceOf(testElement, p5.Element);
assert.instanceOf(testElement, Element);
assert.instanceOf(testElement.elt, HTMLSpanElement);
});

Expand All @@ -387,7 +386,7 @@ suite('DOM', function() {

test('should return p5.Element of image type', function() {
const testElement = mockP5Prototype.createImg(imagePath, '');
assert.instanceOf(testElement, p5.Element);
assert.instanceOf(testElement, Element);
assert.instanceOf(testElement.elt, HTMLImageElement);
});

Expand Down Expand Up @@ -426,7 +425,7 @@ suite('DOM', function() {

test('should return a p5.Element of anchor type', () => {
const testElement = mockP5Prototype.createA('', '');
assert.instanceOf(testElement, p5.Element);
assert.instanceOf(testElement, Element);
assert.instanceOf(testElement.elt, HTMLAnchorElement);
});

Expand All @@ -453,7 +452,7 @@ suite('DOM', function() {

test('should return a p5.Element of slider type', () => {
const testElement = mockP5Prototype.createSlider(0, 100, 0, 1);
assert.instanceOf(testElement, p5.Element);
assert.instanceOf(testElement, Element);
assert.instanceOf(testElement.elt, HTMLInputElement);
assert.deepEqual(testElement.elt.type, 'range');
});
Expand Down Expand Up @@ -482,7 +481,7 @@ suite('DOM', function() {

test('should return a p5.Element of button type', function() {
const testElement = mockP5Prototype.createButton('testButton', 'testButton');
assert.instanceOf(testElement, p5.Element);
assert.instanceOf(testElement, Element);
assert.instanceOf(testElement.elt, HTMLButtonElement);
});

Expand Down Expand Up @@ -522,7 +521,7 @@ suite('DOM', function() {
const testElement = mockP5Prototype.createCheckbox();
const checkboxElement = getCheckboxElement(testElement);

assert.instanceOf(testElement, p5.Element);
assert.instanceOf(testElement, Element);
assert.instanceOf(checkboxElement, HTMLInputElement);
});

Expand All @@ -534,7 +533,7 @@ suite('DOM', function() {
? getSpanElement(testElement).innerHTML
: '';

assert.instanceOf(testElement, p5.Element);
assert.instanceOf(testElement, Element);
assert.instanceOf(spanElement, HTMLSpanElement);
assert.deepEqual(testElementLabelValue, labelValue);
});
Expand All @@ -548,7 +547,7 @@ suite('DOM', function() {
? getSpanElement(testElement).innerHTML
: '';

assert.instanceOf(testElement, p5.Element);
assert.instanceOf(testElement, Element);
assert.instanceOf(spanElement, HTMLSpanElement);
assert.deepEqual(testElementLabelValue, labelValue);
assert.isTrue(testElement.checked());
Expand Down Expand Up @@ -588,7 +587,7 @@ suite('DOM', function() {

test('should return p5.Element of select HTML Element', function() {
const testElement = mockP5Prototype.createSelect();
assert.instanceOf(testElement, p5.Element);
assert.instanceOf(testElement, Element);
assert.instanceOf(testElement.elt, HTMLSelectElement);
});

Expand Down Expand Up @@ -726,7 +725,7 @@ suite('DOM', function() {

test('should return p5.Element of radio type', function() {
const testElement = mockP5Prototype.createRadio();
assert.instanceOf(testElement, p5.Element);
assert.instanceOf(testElement, Element);
assert.instanceOf(testElement.elt, HTMLDivElement);
});

Expand Down Expand Up @@ -866,7 +865,7 @@ suite('DOM', function() {
test('should return p5.Element of input[color] type', function() {
const testElement = mockP5Prototype.createColorPicker();

assert.instanceOf(testElement, p5.Element);
assert.instanceOf(testElement, Element);
assert.instanceOf(testElement.elt, HTMLInputElement);
assert.deepEqual(testElement.elt.type, 'color');
});
Expand Down Expand Up @@ -910,7 +909,7 @@ suite('DOM', function() {

test('should return p5.Element of input type', function() {
const testElement = mockP5Prototype.createInput();
assert.instanceOf(testElement, p5.Element);
assert.instanceOf(testElement, Element);
assert.instanceOf(testElement.elt, HTMLInputElement);
});

Expand Down Expand Up @@ -949,7 +948,7 @@ suite('DOM', function() {

test('should return input of file input', function() {
const testElement = mockP5Prototype.createFileInput(emptyCallback);
assert.instanceOf(testElement, p5.Element);
assert.instanceOf(testElement, Element);
assert.instanceOf(testElement.elt, HTMLInputElement);
assert.deepEqual(testElement.elt.type, 'file');
});
Expand Down Expand Up @@ -1002,244 +1001,6 @@ suite('DOM', function() {
// );
});

// TODO: p5.MediaElement
suite.todo('p5.prototype.createVideo', function() {
afterEach(function() {
document.body.innerHTML = "";
});

const mediaSources = [
'/test/unit/assets/nyan_cat.gif',
'/test/unit/assets/target.gif'
];

test('should be a function', function() {
assert.isFunction(mockP5Prototype.createVideo);
});

test('should return p5.Element of HTMLVideoElement', function() {
const testElement = mockP5Prototype.createVideo('');
assert.instanceOf(testElement, p5.MediaElement);
assert.instanceOf(testElement.elt, HTMLVideoElement);
});

test('should accept a singular media source', function() {
const mediaSource = mediaSources[0];
const testElement = mockP5Prototype.createVideo(mediaSource);
const sourceEl = testElement.elt.children[0];

assert.deepEqual(testElement.elt.childElementCount, 1);
assert.instanceOf(sourceEl, HTMLSourceElement);
assert.isTrue(sourceEl.src.endsWith(mediaSource));
});

test('should accept multiple media sources', function() {
const testElement = mockP5Prototype.createVideo(mediaSources);

assert.deepEqual(testElement.elt.childElementCount, mediaSources.length);
for (let index = 0; index < mediaSources.length; index += 1) {
const sourceEl = testElement.elt.children[index];
assert.instanceOf(sourceEl, HTMLSourceElement);
assert.isTrue(sourceEl.src.endsWith(mediaSources[index]));
}
});

// testSketchWithPromise(
// 'should trigger callback on canplaythrough event',
// function(sketch, resolve, reject) {
// sketch.setup = function() {
// testElement = myp5.createVideo(mediaSources, resolve);
// testElement.elt.dispatchEvent(new Event('canplaythrough'));
// };
// }
// );

// TODO: integration test
test.todo('should work with tint()', function(done) {
const imgElt = myp5.createImg('/test/unit/assets/cat.jpg', '');
const testElement = myp5.createVideo('/test/unit/assets/cat.webm', () => {
// Workaround for headless tests, where the video data isn't loading
// correctly: mock the video element using an image for this test
const prevElt = testElement.elt;
testElement.elt = imgElt.elt;

myp5.background(255);
myp5.tint(255, 0, 0);
myp5.image(testElement, 0, 0);

testElement.elt = prevElt;
imgElt.remove();

myp5.loadPixels();
testElement.loadPixels();
assert.equal(myp5.pixels[0], testElement.pixels[0]);
assert.equal(myp5.pixels[1], 0);
assert.equal(myp5.pixels[2], 0);
done();
});
});

test('should work with updatePixels()', function(done) {
let loaded = false;
let prevElt;
const imgElt = myp5.createImg('/test/unit/assets/cat.jpg', '');
const testElement = myp5.createVideo('/test/unit/assets/cat.webm', () => {
loaded = true;
// Workaround for headless tests, where the video data isn't loading
// correctly: mock the video element using an image for this test
prevElt = testElement.elt;
testElement.elt = imgElt.elt;
});

let drewUpdatedPixels = false;
myp5.draw = function() {
if (!loaded) return;
myp5.background(255);

if (!drewUpdatedPixels) {
// First, update pixels and check that it draws the updated
// pixels correctly
testElement.loadPixels();
for (let i = 0; i < testElement.pixels.length; i += 4) {
// Set every pixel to red
testElement.pixels[i] = 255;
testElement.pixels[i + 1] = 0;
testElement.pixels[i + 2] = 0;
testElement.pixels[i + 3] = 255;
}
testElement.updatePixels();
myp5.image(testElement, 0, 0);

// The element should have drawn using the updated red pixels
myp5.loadPixels();
assert.deepEqual([...myp5.pixels.slice(0, 4)], [255, 0, 0, 255]);

// Mark that we've done the first check so we can see whether
// the video still updates on the next frame
drewUpdatedPixels = true;
} else {
// Next, make sure it still updates with the real pixels from
// the next frame of the video on the next frame of animation
myp5.image(testElement, 0, 0);

myp5.loadPixels();
testElement.loadPixels();
expect([...testElement.pixels.slice(0, 4)])
.to.not.deep.equal([255, 0, 0, 255]);
assert.deepEqual(
[...myp5.pixels.slice(0, 4)],
[...testElement.pixels.slice(0, 4)]
);
testElement.elt = prevElt;
imgElt.remove();
done();
}
};
});
});

suite.todo('p5.prototype.createAudio', function() {
afterEach(function() {
document.body.innerHTML = "";
});

const mediaSources = [
'/test/unit/assets/beat.mp3',
'/test/unit/assets/beat.mp3'
];

test('should be a function', function() {
assert.isFunction(mockP5Prototype.createAudio);
});

test('should return p5.Element of HTMLAudioElement', function() {
const testElement = mockP5Prototype.createAudio('');
assert.instanceOf(testElement, p5.MediaElement);
assert.instanceOf(testElement.elt, HTMLAudioElement);
});

test('should accept a singular media source', function() {
const mediaSource = mediaSources[0];
const testElement = mockP5Prototype.createAudio(mediaSource);
const sourceEl = testElement.elt.children[0];

assert.deepEqual(testElement.elt.childElementCount, 1);
assert.instanceOf(sourceEl, HTMLSourceElement);
assert.isTrue(sourceEl.src.endsWith(mediaSource));
});

test('should accept multiple media sources', function() {
const testElement = mockP5Prototype.createAudio(mediaSources);

assert.deepEqual(testElement.elt.childElementCount, mediaSources.length);
for (let index = 0; index < mediaSources.length; index += 1) {
const sourceEl = testElement.elt.children[index];
assert.instanceOf(sourceEl, HTMLSourceElement);
assert.isTrue(sourceEl.src.endsWith(mediaSources[index]));
}
});

// testSketchWithPromise(
// 'should trigger callback on canplaythrough event',
// function(sketch, resolve, reject) {
// sketch.setup = function() {
// testElement = mockP5Prototype.createAudio(mediaSources, resolve);
// testElement.elt.dispatchEvent(new Event('canplaythrough'));
// };
// }
// );
});

suite.todo('p5.prototype.createCapture', function() {
afterEach(function() {
document.body.innerHTML = "";
});

test('should be a function', function() {
assert.isFunction(mockP5Prototype.createCapture);
});

test('should return p5.Element of video type', function() {
const testElement = mockP5Prototype.createCapture(mockP5Prototype.VIDEO);
assert.instanceOf(testElement, p5.Element);
assert.instanceOf(testElement.elt, HTMLVideoElement);
});

test('should throw error if getUserMedia is not supported', function() {
// Remove getUserMedia method and test
const backup = navigator.mediaDevices.getUserMedia;
navigator.mediaDevices.getUserMedia = undefined;
try {
const testElement = mockP5Prototype.createCapture(mockP5Prototype.VIDEO);
assert.fail();
} catch (error) {
assert.instanceOf(error, DOMException);
}

// Restore backup, very important.
navigator.mediaDevices.getUserMedia = backup;
});

// NOTE: play() failed because the user didn't interact with the document first.
// testSketchWithPromise(
// 'triggers the callback after loading metadata',
// function(sketch, resolve, reject) {
// sketch.setup = function() {
// testElement = myp5.createCapture(myp5.VIDEO, resolve);
// const mockedEvent = new Event('loadedmetadata');
// testElement.elt.dispatchEvent(mockedEvent);
// };
// }
// );

// Required for ios 11 devices
test('should have playsinline attribute to empty string on DOM element', function() {
const testElement = mockP5Prototype.createCapture(mockP5Prototype.VIDEO);
// Weird check, setter accepts : playinline, getter accepts playInline
assert.isTrue(testElement.elt.playsInline);
});
});

suite('p5.prototype.createElement', function() {
afterEach(function() {
document.body.innerHTML = "";
Expand All @@ -1260,7 +1021,7 @@ suite('DOM', function() {
test('should return a p5.Element of appropriate type', function() {
for (const [tag, domElName] of Object.entries(testData)) {
const testElement = mockP5Prototype.createElement(tag);
assert.instanceOf(testElement, p5.Element);
assert.instanceOf(testElement, Element);
assert.instanceOf(testElement.elt, domElName);
}
});
Expand Down
Loading

0 comments on commit ef31f7b

Please sign in to comment.