Commit 8575eb96 authored by Eduardo Sanz García's avatar Eduardo Sanz García Committed by Eduardo

Complete testing of the onDocumentReady function

I removed the `/* istanbul ignore test */` and created a facade to
emulate and iframe for testing.
parent 919e5bf1
...@@ -4,141 +4,191 @@ import { ...@@ -4,141 +4,191 @@ import {
onDocumentReady, onDocumentReady,
} from '../frame-observer'; } from '../frame-observer';
describe('FrameObserver', () => { describe('annotator/frame-observer.js', () => {
let container; describe('FrameObserver', () => {
let frameObserver; let container;
let onFrameAdded; let frameObserver;
let onFrameRemoved; let onFrameAdded;
const sandbox = sinon.createSandbox(); let onFrameRemoved;
const sandbox = sinon.createSandbox();
function waitForFrameObserver() {
return new Promise(resolve => setTimeout(resolve, DEBOUNCE_WAIT + 10)); function waitForFrameObserver() {
} return new Promise(resolve => setTimeout(resolve, DEBOUNCE_WAIT + 10));
}
function createAnnotatableIFrame(
attribute = 'enable-annotation', function createAnnotatableIFrame(
value = '' attribute = 'enable-annotation',
) { value = ''
const iframe = document.createElement('iframe'); ) {
iframe.setAttribute(attribute, value); const iframe = document.createElement('iframe');
container.appendChild(iframe); iframe.setAttribute(attribute, value);
return iframe; container.appendChild(iframe);
} return iframe;
}
function waitForIFrameUnload(iframe) {
return new Promise(resolve => function waitForIFrameUnload(iframe) {
iframe.contentWindow.addEventListener('unload', resolve) return new Promise(resolve =>
); iframe.contentWindow.addEventListener('unload', resolve)
} );
}
beforeEach(() => {
container = document.createElement('div'); beforeEach(() => {
document.body.appendChild(container); container = document.createElement('div');
onFrameAdded = sandbox.stub(); document.body.appendChild(container);
onFrameRemoved = sandbox.stub(); onFrameAdded = sandbox.stub();
frameObserver = new FrameObserver(container, onFrameAdded, onFrameRemoved); onFrameRemoved = sandbox.stub();
sandbox.stub(console, 'warn'); frameObserver = new FrameObserver(
}); container,
onFrameAdded,
onFrameRemoved
);
sandbox.stub(console, 'warn');
});
afterEach(() => { afterEach(() => {
container.remove(); container.remove();
frameObserver.disconnect(); frameObserver.disconnect();
sandbox.restore(); sandbox.restore();
}); });
it('triggers onFrameAdded when an annotatable iframe is added', async () => { it('triggers onFrameAdded when an annotatable iframe is added', async () => {
let iframe = createAnnotatableIFrame(); let iframe = createAnnotatableIFrame();
await waitForFrameObserver(); await waitForFrameObserver();
assert.calledWith(onFrameAdded, iframe); assert.calledWith(onFrameAdded, iframe);
iframe = createAnnotatableIFrame('enable-annotation', 'yes'); iframe = createAnnotatableIFrame('enable-annotation', 'yes');
await waitForFrameObserver(); await waitForFrameObserver();
assert.calledWith(onFrameAdded, iframe); assert.calledWith(onFrameAdded, iframe);
iframe = createAnnotatableIFrame('enable-annotation', 'true'); iframe = createAnnotatableIFrame('enable-annotation', 'true');
await waitForFrameObserver(); await waitForFrameObserver();
assert.calledWith(onFrameAdded, iframe); assert.calledWith(onFrameAdded, iframe);
iframe = createAnnotatableIFrame('enable-annotation', '1'); iframe = createAnnotatableIFrame('enable-annotation', '1');
await waitForFrameObserver(); await waitForFrameObserver();
assert.calledWith(onFrameAdded, iframe); assert.calledWith(onFrameAdded, iframe);
iframe = createAnnotatableIFrame('enable-annotation', 'false'); // the actual value of the attribute is irrelevant iframe = createAnnotatableIFrame('enable-annotation', 'false'); // the actual value of the attribute is irrelevant
await waitForFrameObserver(); await waitForFrameObserver();
assert.calledWith(onFrameAdded, iframe); assert.calledWith(onFrameAdded, iframe);
}); });
it("doesn't trigger onFrameAdded when non-annotatable iframes are added", async () => { it("doesn't trigger onFrameAdded when non-annotatable iframes are added", async () => {
createAnnotatableIFrame('dummy-attribute'); createAnnotatableIFrame('dummy-attribute');
await waitForFrameObserver(); await waitForFrameObserver();
assert.notCalled(onFrameAdded); assert.notCalled(onFrameAdded);
}); });
it('removal of the annotatable iframe triggers onFrameRemoved', async () => { it('removal of the annotatable iframe triggers onFrameRemoved', async () => {
const iframe = createAnnotatableIFrame(); const iframe = createAnnotatableIFrame();
await waitForFrameObserver(); await waitForFrameObserver();
assert.calledOnce(onFrameAdded); assert.calledOnce(onFrameAdded);
assert.calledWith(onFrameAdded, iframe); assert.calledWith(onFrameAdded, iframe);
iframe.remove(); iframe.remove();
await waitForFrameObserver(); await waitForFrameObserver();
assert.calledOnce(onFrameRemoved); assert.calledOnce(onFrameRemoved);
assert.calledWith(onFrameRemoved, iframe); assert.calledWith(onFrameRemoved, iframe);
}); });
it('removal of the `enable-annotation` attribute triggers onFrameRemoved', async () => { it('removal of the `enable-annotation` attribute triggers onFrameRemoved', async () => {
const iframe = createAnnotatableIFrame(); const iframe = createAnnotatableIFrame();
await waitForFrameObserver(); await waitForFrameObserver();
assert.calledOnce(onFrameAdded); assert.calledOnce(onFrameAdded);
assert.calledWith(onFrameAdded, iframe); assert.calledWith(onFrameAdded, iframe);
iframe.removeAttribute('enable-annotation'); iframe.removeAttribute('enable-annotation');
await waitForFrameObserver(); await waitForFrameObserver();
assert.calledOnce(onFrameRemoved); assert.calledOnce(onFrameRemoved);
assert.calledWith(onFrameRemoved, iframe); assert.calledWith(onFrameRemoved, iframe);
}); });
it('changing the `src` attribute triggers onFrameRemoved', async () => { it('changing the `src` attribute triggers onFrameRemoved', async () => {
const iframe = createAnnotatableIFrame(); const iframe = createAnnotatableIFrame();
await waitForFrameObserver(); await waitForFrameObserver();
assert.calledOnce(onFrameAdded); assert.calledOnce(onFrameAdded);
assert.calledWith(onFrameAdded, iframe); assert.calledWith(onFrameAdded, iframe);
iframe.setAttribute('src', document.location); iframe.setAttribute('src', document.location);
await waitForIFrameUnload(iframe); await waitForIFrameUnload(iframe);
assert.calledOnce(onFrameRemoved); assert.calledOnce(onFrameRemoved);
assert.calledWith(onFrameRemoved, iframe); assert.calledWith(onFrameRemoved, iframe);
}); });
it(`doesn't call onFrameAdded if FrameObserver is disconnected`, async () => { it(`doesn't call onFrameAdded if FrameObserver is disconnected`, async () => {
frameObserver.disconnect(); frameObserver.disconnect();
const iframe = createAnnotatableIFrame(); const iframe = createAnnotatableIFrame();
frameObserver._discoverFrames(); // Emulate a race condition frameObserver._discoverFrames(); // Emulate a race condition
await onDocumentReady(iframe); await onDocumentReady(iframe);
assert.notCalled(onFrameAdded); assert.notCalled(onFrameAdded);
}); });
it("doesn't trigger onFrameAdded when annotatable iframe is from a different domain", async () => {
const iframe = createAnnotatableIFrame();
iframe.setAttribute('src', 'http://cross-origin.dummy');
it("doesn't trigger onFrameAdded when annotatable iframe is from a different domain", async () => { await onDocumentReady(iframe);
const iframe = createAnnotatableIFrame(); await waitForFrameObserver();
iframe.setAttribute('src', 'http://cross-origin.dummy');
assert.notCalled(onFrameAdded);
assert.calledOnce(console.warn);
});
});
await onDocumentReady(iframe); describe('onDocumentReady', () => {
await waitForFrameObserver(); let fakeIFrame;
assert.notCalled(onFrameAdded); let fakeIFrameDocument;
assert.calledOnce(console.warn);
beforeEach(() => {
fakeIFrameDocument = {
addEventListener: sinon.stub(),
readyState: 'loading',
location: {
href: 'about:blank',
},
};
fakeIFrame = {
contentWindow: {
document: fakeIFrameDocument,
},
addEventListener: sinon.stub(),
hasAttribute: sinon.stub(),
};
});
it('waits for the iframe load event to be triggered if the document is blank', () => {
fakeIFrameDocument.location.href = 'about:blank';
fakeIFrame.hasAttribute.returns(true);
onDocumentReady(fakeIFrame);
assert.calledWith(fakeIFrame.addEventListener, 'load');
});
it('waits for the iframe DOMContentLoaded event to be triggered if the document is loading', () => {
fakeIFrameDocument.location.href = 'about:srcdoc';
fakeIFrame.hasAttribute.returns(false);
fakeIFrameDocument.readyState = 'loading';
onDocumentReady(fakeIFrame);
assert.calledWith(
fakeIFrameDocument.addEventListener,
'DOMContentLoaded'
);
});
}); });
}); });
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment