/
githubmirror
/
amphtml
Обзор
Документация
Войти
/
githubmirror
/
amphtml
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
test/unit/test-3p-environment.js
243 строки
8 KB
Ryan Cebulko
♻️ Move files into #core, #utils to enable tsc typechecking (#36277)
07 окт 2021, 23:26
Не верифицирован
07 окт 2021, 23:26
b6d1550
Код
Авторство
О чём код?
import * as fakeTimers from '@sinonjs/fake-timers'; import {manageWin, setInViewportForTesting} from '#3p/environment'; import {Services} from '#service'; import {loadPromise} from '#utils/event-helper'; import {createIframePromise} from '#testing/iframe'; describes.sandboxed('3p environment', {}, () => { let testWin; let iframeCount; const timer = Services.timerFor(window); beforeEach(() => { iframeCount = 0; return createIframePromise(true).then((iframe) => { testWin = iframe.win; }); }); it('should instrument a window', () => { expect(testWin.setTimeout).to.match(/native/); manageWin(testWin); testWindow(testWin); }); it('should instrument dynamically created child iframes: srcdoc', () => { expect(testWin.setTimeout).to.match(/native/); manageWin(testWin); const iframe = makeChildIframeSrcdoc(testWin); testWindow(testWin); return waitForMutationObserver(iframe).then(() => { testWindow(iframe.contentWindow); }); }); it('should instrument dynamically created child iframes: doc.write', () => { expect(testWin.setTimeout).to.match(/native/); manageWin(testWin); const iframe = makeChildIframeDocWrite(testWin); testWindow(testWin); return waitForMutationObserver(iframe).then(() => { testWindow(iframe.contentWindow); }); }); it('should instrument nested child iframes: doc.write', () => { expect(testWin.setTimeout).to.match(/native/); manageWin(testWin); const iframe = makeChildIframeDocWrite(testWin); testWindow(testWin); return waitForMutationObserver(iframe).then(() => { testWindow(iframe.contentWindow); const i0 = makeChildIframeDocWrite(iframe.contentWindow); const i1 = makeChildIframeDocWrite(iframe.contentWindow); return waitForMutationObserver(i1).then(() => { testWindow(i0.contentWindow); testWindow(i1.contentWindow); const i2 = makeChildIframeDocWrite(iframe.contentWindow); return waitForMutationObserver(i2).then(() => { testWindow(i2.contentWindow); }); }); }); }); it('should instrument nested child iframes: mixed', () => { expect(testWin.setTimeout).to.match(/native/); manageWin(testWin); const iframe = makeChildIframeSrcdoc(testWin); testWindow(testWin); return waitForMutationObserver(iframe).then(() => { testWindow(iframe.contentWindow); const i0 = makeChildIframeDocWrite(iframe.contentWindow); const i1 = makeChildIframeDocWrite(iframe.contentWindow); return waitForMutationObserver(i1).then(() => { testWindow(i0.contentWindow); testWindow(i1.contentWindow); const i2 = makeChildIframeDocWrite(iframe.contentWindow); return waitForMutationObserver(i2).then(() => { testWindow(i2.contentWindow); }); }); }); }); describe('timers', function () { let clock; let progress; beforeEach(() => { progress = ''; // testWin is created before each test and destroyed when the iframe it // comes from gets detached, causing bugs if we call clock.uninstall(). clock = fakeTimers.withGlobal(testWin).install(); }); function add(p) { return function (a, b) { progress += p; if (a) { progress += a; } if (b) { progress += b; } }; } it('throttle setTimeout', () => { manageWin(testWin); testWin.setTimeout(add('a'), 50); testWin.setTimeout(add('b'), 60); testWin.setTimeout(add('c'), 100); clock.tick(99); expect(progress).to.equal('ab'); clock.tick(1); expect(progress).to.equal('abc'); setInViewportForTesting(false); testWin.setTimeout(add('d'), 100); const t0 = testWin.setTimeout(add('canceled'), 100); testWin.clearTimeout(t0); clock.tick(100); expect(progress).to.equal('abc'); clock.tick(999); expect(progress).to.equal('abc'); clock.tick(1); expect(progress).to.equal('abcd'); setInViewportForTesting(true); testWin.setTimeout(add('e'), 100); const t1 = testWin.setTimeout(add('canceled'), 100); testWin.clearTimeout(t1); clock.tick(100); expect(progress).to.equal('abcde'); }); it('throttle setInterval', () => { manageWin(testWin); const ia = testWin.setInterval(add('a'), 1); testWin.setInterval(add('b'), 10); const ic = testWin.setInterval(add('c'), 20); clock.tick(20); expect(progress).to.equal('aaaaaaaaabaaaaaaaaaacba'); setInViewportForTesting(false); clock.tick(20); expect(progress).to.equal('aaaaaaaaabaaaaaaaaaacbaabc'); clock.tick(980); expect(progress).to.equal('aaaaaaaaabaaaaaaaaaacbaabc'); setInViewportForTesting(true); clock.tick(20); expect(progress).to.equal( 'aaaaaaaaabaaaaaaaaaacbaabcaaaaaaaaaaaaaaaaaaba' ); testWin.clearInterval(ia); testWin.clearInterval(ic); clock.tick(20); expect(progress).to.equal( 'aaaaaaaaabaaaaaaaaaacbaabcaaaaaaaaaaaaaaaaaababb' ); testWin.ran = false; testWin.setInterval('ran=true', 1); clock.tick(1); expect(window.ran).to.be.equal(undefined); expect(testWin.ran).to.be.true; }); it('should support multi arg forms', () => { manageWin(testWin); testWin.setTimeout(add('a'), 50, '!', '?'); testWin.setTimeout(add('b'), 60, 'B'); testWin.setInterval(add('i'), 70, 'X', 'Z'); clock.tick(140); expect(progress).to.equal('a!?bBiXZiXZ'); }); it('should cancel uninstrumented timeouts', () => { const timeout = testWin.setTimeout(() => { throw new Error('should not happen: timeout'); }, 0); const interval = testWin.setInterval(() => { throw new Error('should not happen: interval'); }, 0); manageWin(testWin); testWin.clearTimeout(timeout); testWin.clearInterval(interval); clock.tick(100); }); }); function testWindow(win) { expect(win.ampSeen).to.be.true; expect(win.setTimeout).to.not.match(/native/); expect(win.setInterval).to.not.match(/native/); expect(win.alert.toString()).to.not.match(/native/); expect(win.prompt.toString()).to.not.match(/native/); expect(win.confirm.toString()).to.not.match(/native/); expect(win.alert()).to.be.undefined; expect(win.prompt()).to.equal(''); expect(win.confirm()).to.be.false; // We only allow 3 calls to these functions. expect(() => win.alert()).to.throw(/security error/); expect(() => win.prompt()).to.throw(/security error/); expect(() => win.confirm()).to.throw(/security error/); } function waitForMutationObserver(iframe) { if ( iframe.contentWindow && iframe.contentWindow.document && iframe.contentWindow.document.body.childNodes.length ) { return timer.promise(10); } return loadPromise(iframe).then(() => { return timer.promise(10); }); } function makeChildIframeSrcdoc(win) { const doc = win.document; const iframe = doc.createElement('iframe'); iframe.name = 'testChild' + iframeCount++; iframe.setAttribute('srcdoc', 'hello: ' + iframe.name); doc.body.appendChild(iframe); doc.body.appendChild(doc.createElement('hr')); return iframe; } function makeChildIframeDocWrite(win) { const doc = win.document; const iframe = doc.createElement('iframe'); iframe.name = 'testChild' + iframeCount++; iframe.src = 'about:blank'; doc.body.appendChild(iframe); iframe.contentWindow.document.open(); iframe.contentWindow.document.write('write: ' + iframe.name); iframe.contentWindow.document.close(); doc.body.appendChild(doc.createElement('hr')); return iframe; } });