diff --git a/extensions/amp-3d-gltf/0.1/test/test-amp-3d-gltf.js b/extensions/amp-3d-gltf/0.1/test/test-amp-3d-gltf.js index 019c57791052..406461fdad0a 100644 --- a/extensions/amp-3d-gltf/0.1/test/test-amp-3d-gltf.js +++ b/extensions/amp-3d-gltf/0.1/test/test-amp-3d-gltf.js @@ -59,7 +59,7 @@ describes.realWin( doc.body.appendChild(amp3dGltfEl); await amp3dGltfEl.build(); - const amp3dGltf = amp3dGltfEl.implementation_; + const amp3dGltf = await amp3dGltfEl.getImpl(); env.sandbox .stub(amp3dGltf, 'iframe_') .get(() => iframe) diff --git a/extensions/amp-3q-player/0.1/test/test-amp-3q-player.js b/extensions/amp-3q-player/0.1/test/test-amp-3q-player.js index b511968d2a27..672bba5de092 100644 --- a/extensions/amp-3q-player/0.1/test/test-amp-3q-player.js +++ b/extensions/amp-3q-player/0.1/test/test-amp-3q-player.js @@ -50,7 +50,8 @@ describes.realWin( await player.build(); player.layoutCallback(); const iframe = player.querySelector('iframe'); - player.implementation_.sdnBridge_({ + const impl = await player.getImpl(); + impl.sdnBridge_({ source: iframe.contentWindow, data: JSON.stringify({data: 'ready'}), }); @@ -76,25 +77,26 @@ describes.realWin( it('should forward events from amp-3q-player to the amp element', async () => { const player = await get3QElement('c8dbe7f4-7f7f-11e6-a407-0cc47a188158'); + const impl = await player.getImpl(); const iframe = player.querySelector('iframe'); await Promise.resolve(); const p1 = listenOncePromise(player, VideoEvents.MUTED); - sendFakeMessage(player, iframe, 'muted'); + sendFakeMessage(impl, iframe, 'muted'); await p1; const p2 = listenOncePromise(player, VideoEvents.PLAYING); - sendFakeMessage(player, iframe, 'playing'); + sendFakeMessage(impl, iframe, 'playing'); await p2; const p3 = listenOncePromise(player, VideoEvents.PAUSE); - sendFakeMessage(player, iframe, 'paused'); + sendFakeMessage(impl, iframe, 'paused'); await p3; const p4 = listenOncePromise(player, VideoEvents.UNMUTED); - sendFakeMessage(player, iframe, 'unmuted'); + sendFakeMessage(impl, iframe, 'unmuted'); const successTimeout = timer.promise(10); return Promise.race([p4, successTimeout]); }); - function sendFakeMessage(player, iframe, command) { - player.implementation_.sdnBridge_({ + function sendFakeMessage(impl, iframe, command) { + impl.sdnBridge_({ source: iframe.contentWindow, data: JSON.stringify({data: command}), }); diff --git a/extensions/amp-accordion/0.1/test/test-amp-accordion.js b/extensions/amp-accordion/0.1/test/test-amp-accordion.js index d4acba2b35b9..1d9a55f13a2f 100644 --- a/extensions/amp-accordion/0.1/test/test-amp-accordion.js +++ b/extensions/amp-accordion/0.1/test/test-amp-accordion.js @@ -65,8 +65,9 @@ describes.realWin( doc.body.appendChild(ampAccordion); return ampAccordion .build() - .then(() => { - ampAccordion.implementation_.mutateElement = (fn) => + .then(() => ampAccordion.getImpl()) + .then((impl) => { + impl.mutateElement = (fn) => new Promise(() => { fn(); }); @@ -99,270 +100,215 @@ describes.realWin( impl.executeAction(invocation); } - it('should expand when high trust toggle action is triggered on a collapsed section', () => { - return getAmpAccordion().then((ampAccordion) => { - const impl = ampAccordion.implementation_; - const headerElements = doc.querySelectorAll('section > *:first-child'); - expect(headerElements[0].parentNode.hasAttribute('expanded')).to.be - .false; - expect(headerElements[0].getAttribute('aria-expanded')).to.equal( - 'false' - ); - impl.toggle_(headerElements[0].parentNode, ActionTrust.HIGH); - expect(headerElements[0].parentNode.hasAttribute('expanded')).to.be - .true; - expect(headerElements[0].getAttribute('aria-expanded')).to.equal( - 'true' - ); - }); + it('should expand when high trust toggle action is triggered on a collapsed section', async () => { + const ampAccordion = await getAmpAccordion(); + const impl = await ampAccordion.getImpl(); + const headerElements = doc.querySelectorAll('section > *:first-child'); + expect(headerElements[0].parentNode.hasAttribute('expanded')).to.be.false; + expect(headerElements[0].getAttribute('aria-expanded')).to.equal('false'); + impl.toggle_(headerElements[0].parentNode, ActionTrust.HIGH); + expect(headerElements[0].parentNode.hasAttribute('expanded')).to.be.true; + expect(headerElements[0].getAttribute('aria-expanded')).to.equal('true'); }); - it('multiple accordions should not have the same IDs on content', () => { - return getAmpAccordion().then(() => { - return getAmpAccordion().then(() => { - const contentElements = doc.getElementsByClassName( - 'i-amphtml-accordion-content' - ); - for (let i = 0; i < contentElements.length; i++) { - expect(contentElements[i].id.startsWith('_AMP_content_')).to.be - .false; - } - }); - }); + it('multiple accordions should not have the same IDs on content', async () => { + await getAmpAccordion(); + const contentElements = doc.getElementsByClassName( + 'i-amphtml-accordion-content' + ); + for (let i = 0; i < contentElements.length; i++) { + expect(contentElements[i].id.startsWith('_AMP_content_')).to.be.false; + } }); - it('should collapse when high trust toggle action is triggered on a expanded section', () => { - return getAmpAccordion().then((ampAccordion) => { - const impl = ampAccordion.implementation_; - const headerElements = doc.querySelectorAll('section > *:first-child'); - expect(headerElements[1].parentNode.hasAttribute('expanded')).to.be - .true; - expect(headerElements[1].getAttribute('aria-expanded')).to.equal( - 'true' - ); + it('should collapse when high trust toggle action is triggered on a expanded section', async () => { + const ampAccordion = await getAmpAccordion(); + const impl = await ampAccordion.getImpl(); + const headerElements = doc.querySelectorAll('section > *:first-child'); + expect(headerElements[1].parentNode.hasAttribute('expanded')).to.be.true; + expect(headerElements[1].getAttribute('aria-expanded')).to.equal('true'); - impl.toggle_(headerElements[1].parentNode, ActionTrust.HIGH); + impl.toggle_(headerElements[1].parentNode, ActionTrust.HIGH); - expect(headerElements[1].parentNode.hasAttribute('expanded')).to.be - .false; - expect(headerElements[1].getAttribute('aria-expanded')).to.equal( - 'false' - ); - }); + expect(headerElements[1].parentNode.hasAttribute('expanded')).to.be.false; + expect(headerElements[1].getAttribute('aria-expanded')).to.equal('false'); }); - it('should expand when expand action is triggered on a collapsed section', () => { - return getAmpAccordion().then((ampAccordion) => { - const impl = ampAccordion.implementation_; - const headerElements = doc.querySelectorAll('section > *:first-child'); - expect(headerElements[0].parentNode.hasAttribute('expanded')).to.be - .false; - expect(headerElements[0].getAttribute('aria-expanded')).to.equal( - 'false' - ); - impl.toggle_(headerElements[0].parentNode, ActionTrust.HIGH, true); - expect(headerElements[0].parentNode.hasAttribute('expanded')).to.be - .true; - expect(headerElements[0].getAttribute('aria-expanded')).to.equal( - 'true' - ); - }); + it('should expand when expand action is triggered on a collapsed section', async () => { + const ampAccordion = await getAmpAccordion(); + const impl = await ampAccordion.getImpl(); + const headerElements = doc.querySelectorAll('section > *:first-child'); + expect(headerElements[0].parentNode.hasAttribute('expanded')).to.be.false; + expect(headerElements[0].getAttribute('aria-expanded')).to.equal('false'); + impl.toggle_(headerElements[0].parentNode, ActionTrust.HIGH, true); + expect(headerElements[0].parentNode.hasAttribute('expanded')).to.be.true; + expect(headerElements[0].getAttribute('aria-expanded')).to.equal('true'); }); it( 'should collapse other sections when expand action is triggered on a ' + 'collapsed section if expand-single-section attribute is set', - () => { - return getAmpAccordion().then((ampAccordion) => { - ampAccordion.setAttribute('expand-single-section', ''); - expect(ampAccordion.hasAttribute('expand-single-section')).to.be.true; - const impl = ampAccordion.implementation_; - const headerElements = doc.querySelectorAll( - 'section > *:first-child' - ); - // second section is expanded by default - expect(headerElements[1].parentNode.hasAttribute('expanded')).to.be - .true; - expect(headerElements[1].getAttribute('aria-expanded')).to.equal( - 'true' - ); - // expand the first section - impl.toggle_(headerElements[0].parentNode, ActionTrust.HIGH, true); - // we expect the first section to be expanded - expect(headerElements[0].parentNode.hasAttribute('expanded')).to.be - .true; - expect(headerElements[0].getAttribute('aria-expanded')).to.equal( - 'true' - ); - // we expect the second section to be collapsed - expect(headerElements[1].parentNode.hasAttribute('expanded')).to.be - .false; - expect(headerElements[1].getAttribute('aria-expanded')).to.equal( - 'false' - ); - }); - } - ); - - it('should expand when low trust toggle action is triggered on a collapsed section', () => { - return getAmpAccordion().then((ampAccordion) => { - const impl = ampAccordion.implementation_; + async () => { + const ampAccordion = await getAmpAccordion(); + const impl = await ampAccordion.getImpl(); + ampAccordion.setAttribute('expand-single-section', ''); + expect(ampAccordion.hasAttribute('expand-single-section')).to.be.true; const headerElements = doc.querySelectorAll('section > *:first-child'); - expect(headerElements[0].parentNode.hasAttribute('expanded')).to.be - .false; - expect(headerElements[0].getAttribute('aria-expanded')).to.equal( - 'false' - ); - impl.toggle_(headerElements[0].parentNode, ActionTrust.LOW); - expect(headerElements[0].parentNode.hasAttribute('expanded')).to.be + // second section is expanded by default + expect(headerElements[1].parentNode.hasAttribute('expanded')).to.be .true; - expect(headerElements[0].getAttribute('aria-expanded')).to.equal( + expect(headerElements[1].getAttribute('aria-expanded')).to.equal( 'true' ); - }); - }); - - it('should collapse when low trust toggle action is triggered on an expanded section', () => { - return getAmpAccordion().then((ampAccordion) => { - const impl = ampAccordion.implementation_; - const headerElements = doc.querySelectorAll('section > *:first-child'); - expect(headerElements[1].parentNode.hasAttribute('expanded')).to.be + // expand the first section + impl.toggle_(headerElements[0].parentNode, ActionTrust.HIGH, true); + // we expect the first section to be expanded + expect(headerElements[0].parentNode.hasAttribute('expanded')).to.be .true; - expect(headerElements[1].getAttribute('aria-expanded')).to.equal( + expect(headerElements[0].getAttribute('aria-expanded')).to.equal( 'true' ); - - impl.toggle_(headerElements[1].parentNode, ActionTrust.LOW); - + // we expect the second section to be collapsed expect(headerElements[1].parentNode.hasAttribute('expanded')).to.be .false; expect(headerElements[1].getAttribute('aria-expanded')).to.equal( 'false' ); - }); + } + ); + + it('should expand when low trust toggle action is triggered on a collapsed section', async () => { + const ampAccordion = await getAmpAccordion(); + const impl = await ampAccordion.getImpl(); + const headerElements = doc.querySelectorAll('section > *:first-child'); + expect(headerElements[0].parentNode.hasAttribute('expanded')).to.be.false; + expect(headerElements[0].getAttribute('aria-expanded')).to.equal('false'); + impl.toggle_(headerElements[0].parentNode, ActionTrust.LOW); + expect(headerElements[0].parentNode.hasAttribute('expanded')).to.be.true; + expect(headerElements[0].getAttribute('aria-expanded')).to.equal('true'); }); - it('should expand when beforematch event is triggered on a collapsed section', () => { + it('should collapse when low trust toggle action is triggered on an expanded section', async () => { + const ampAccordion = await getAmpAccordion(); + const impl = await ampAccordion.getImpl(); + const headerElements = doc.querySelectorAll('section > *:first-child'); + expect(headerElements[1].parentNode.hasAttribute('expanded')).to.be.true; + expect(headerElements[1].getAttribute('aria-expanded')).to.equal('true'); + + impl.toggle_(headerElements[1].parentNode, ActionTrust.LOW); + + expect(headerElements[1].parentNode.hasAttribute('expanded')).to.be.false; + expect(headerElements[1].getAttribute('aria-expanded')).to.equal('false'); + }); + + it('should expand when beforematch event is triggered on a collapsed section', async () => { // Enable display locking feature. toggleExperiment(win, 'amp-accordion-display-locking', true); doc.body.onbeforematch = null; - return getAmpAccordion().then(() => { - const section = doc.querySelector('section:not([expanded])'); - const header = section.firstElementChild; - const content = section.children[1]; - expect(section.hasAttribute('expanded')).to.be.false; - expect(header.getAttribute('aria-expanded')).to.equal('false'); - content.dispatchEvent(new Event('beforematch')); - expect(section.hasAttribute('expanded')).to.be.true; - expect(header.getAttribute('aria-expanded')).to.equal('true'); - - // Reset display locking feature - toggleExperiment(win, 'amp-accordion-display-locking', false); - doc.body.onbeforematch = undefined; - }); + await getAmpAccordion(); + const section = doc.querySelector('section:not([expanded])'); + const header = section.firstElementChild; + const content = section.children[1]; + expect(section.hasAttribute('expanded')).to.be.false; + expect(header.getAttribute('aria-expanded')).to.equal('false'); + content.dispatchEvent(new Event('beforematch')); + expect(section.hasAttribute('expanded')).to.be.true; + expect(header.getAttribute('aria-expanded')).to.equal('true'); + + // Reset display locking feature + toggleExperiment(win, 'amp-accordion-display-locking', false); + doc.body.onbeforematch = undefined; }); it( "should trigger a section's expand event the section is expanded " + 'without animation', - () => { - let impl; - return getAmpAccordion(true) - .then((ampAccordion) => { - impl = ampAccordion.implementation_; - impl.sections_[0].setAttribute( - 'on', - `expand:acc${counter}.expand(section='acc${counter}sec${2}')` - ); - expect(impl.sections_[2].hasAttribute('expanded')).to.be.false; - impl.toggle_(impl.sections_[0], ActionTrust.HIGH, true); - return poll('wait for first section to expand', () => - impl.sections_[0].hasAttribute('expanded') - ); - }) - .then(() => { - expect(impl.sections_[2].hasAttribute('expanded')).to.be.true; - }); + async () => { + const ampAccordion = await getAmpAccordion(true); + const impl = await ampAccordion.getImpl(); + + impl.sections_[0].setAttribute( + 'on', + `expand:acc${counter}.expand(section='acc${counter}sec${2}')` + ); + expect(impl.sections_[2].hasAttribute('expanded')).to.be.false; + impl.toggle_(impl.sections_[0], ActionTrust.HIGH, true); + + await poll('wait for first section to expand', () => + impl.sections_[0].hasAttribute('expanded') + ); + expect(impl.sections_[2].hasAttribute('expanded')).to.be.true; } ); it( "should trigger a section's collapse event the section is expanded " + 'without animation', - () => { - let impl; - return getAmpAccordion(true) - .then((ampAccordion) => { - impl = ampAccordion.implementation_; - impl.sections_[1].setAttribute( - 'on', - `collapse:acc${counter}.expand(section='acc${counter}sec${2}')` - ); - expect(impl.sections_[2].hasAttribute('expanded')).to.be.false; - impl.toggle_(impl.sections_[1], ActionTrust.HIGH, false); - return poll( - 'wait for first section to expand', - () => !impl.sections_[1].hasAttribute('expanded') - ); - }) - .then(() => { - expect(impl.sections_[2].hasAttribute('expanded')).to.be.true; - }); + async () => { + const ampAccordion = await getAmpAccordion(true); + const impl = await ampAccordion.getImpl(); + + impl.sections_[1].setAttribute( + 'on', + `collapse:acc${counter}.expand(section='acc${counter}sec${2}')` + ); + expect(impl.sections_[2].hasAttribute('expanded')).to.be.false; + impl.toggle_(impl.sections_[1], ActionTrust.HIGH, false); + + await poll( + 'wait for first section to expand', + () => !impl.sections_[1].hasAttribute('expanded') + ); + expect(impl.sections_[2].hasAttribute('expanded')).to.be.true; } ); it( "should trigger a section's expand event the section is expanded " + 'with animation', - () => { - let impl; - return getAmpAccordion(true) - .then((ampAccordion) => { - ampAccordion.setAttribute('animate', ''); - impl = ampAccordion.implementation_; - impl.sections_[0].setAttribute( - 'on', - `expand:acc${counter}.expand(section='acc${counter}sec${2}')` - ); - expect(impl.sections_[2].hasAttribute('expanded')).to.be.false; - impl.toggle_(impl.sections_[0], ActionTrust.HIGH, true); - return poll('wait for first section to expand', () => - impl.sections_[0].hasAttribute('expanded') - ); - }) - .then(() => { - return poll('wait for second section to expand', () => - impl.sections_[2].hasAttribute('expanded') - ); - }); + async () => { + const ampAccordion = await getAmpAccordion(true); + const impl = await ampAccordion.getImpl(); + + ampAccordion.setAttribute('animate', ''); + impl.sections_[0].setAttribute( + 'on', + `expand:acc${counter}.expand(section='acc${counter}sec${2}')` + ); + expect(impl.sections_[2].hasAttribute('expanded')).to.be.false; + impl.toggle_(impl.sections_[0], ActionTrust.HIGH, true); + + await poll('wait for first section to expand', () => + impl.sections_[0].hasAttribute('expanded') + ); + await poll('wait for second section to expand', () => + impl.sections_[2].hasAttribute('expanded') + ); } ); it( "should trigger a section's collapse event the section is expanded " + 'with animation', - () => { - let impl; - return getAmpAccordion(true) - .then((ampAccordion) => { - ampAccordion.setAttribute('animate', ''); - impl = ampAccordion.implementation_; - impl.sections_[1].setAttribute( - 'on', - `collapse:acc${counter}.expand(section='acc${counter}sec${2}')` - ); - expect(impl.sections_[2].hasAttribute('expanded')).to.be.false; - impl.toggle_(impl.sections_[1], ActionTrust.HIGH, false); - return poll( - 'wait for first section to expand', - () => !impl.sections_[1].hasAttribute('expanded') - ); - }) - .then(() => { - return poll('wait for second section to expand', () => - impl.sections_[2].hasAttribute('expanded') - ); - }); + async () => { + const ampAccordion = await getAmpAccordion(true); + const impl = await ampAccordion.getImpl(); + + ampAccordion.setAttribute('animate', ''); + impl.sections_[1].setAttribute( + 'on', + `collapse:acc${counter}.expand(section='acc${counter}sec${2}')` + ); + expect(impl.sections_[2].hasAttribute('expanded')).to.be.false; + impl.toggle_(impl.sections_[1], ActionTrust.HIGH, false); + + await poll( + 'wait for first section to expand', + () => !impl.sections_[1].hasAttribute('expanded') + ); + await poll('wait for second section to expand', () => + impl.sections_[2].hasAttribute('expanded') + ); } ); @@ -374,7 +320,7 @@ describes.realWin( `, ]; const ampAccordion = await getAmpAccordionWithContents(contents, true); - const impl = ampAccordion.implementation_; + const impl = await ampAccordion.getImpl(); const firstSection = impl.sections_[0]; const content = firstSection.querySelector('amp-layout'); @@ -402,7 +348,7 @@ describes.realWin( `, ]; const ampAccordion = await getAmpAccordionWithContents(contents, true); - const impl = ampAccordion.implementation_; + const impl = await ampAccordion.getImpl(); const firstSection = impl.sections_[0]; const content = firstSection.querySelector('amp-layout'); @@ -422,64 +368,117 @@ describes.realWin( }); }); - it('should stay expanded on the expand action when expanded', () => { - return getAmpAccordion().then((ampAccordion) => { - const impl = ampAccordion.implementation_; - const headerElements = doc.querySelectorAll('section > *:first-child'); - expect(headerElements[1].parentNode.hasAttribute('expanded')).to.be - .true; - expect(headerElements[1].getAttribute('aria-expanded')).to.equal( - 'true' - ); - impl.toggle_(headerElements[1].parentNode, ActionTrust.HIGH, true); - expect(headerElements[1].parentNode.hasAttribute('expanded')).to.be - .true; - expect(headerElements[1].getAttribute('aria-expanded')).to.equal( - 'true' - ); - }); + it('should stay expanded on the expand action when expanded', async () => { + const ampAccordion = await getAmpAccordion(); + const impl = await ampAccordion.getImpl(); + const headerElements = doc.querySelectorAll('section > *:first-child'); + expect(headerElements[1].parentNode.hasAttribute('expanded')).to.be.true; + expect(headerElements[1].getAttribute('aria-expanded')).to.equal('true'); + impl.toggle_(headerElements[1].parentNode, ActionTrust.HIGH, true); + expect(headerElements[1].parentNode.hasAttribute('expanded')).to.be.true; + expect(headerElements[1].getAttribute('aria-expanded')).to.equal('true'); }); - it('should collapse on the collapse action when expanded', () => { - return getAmpAccordion().then((ampAccordion) => { - const impl = ampAccordion.implementation_; - const headerElements = doc.querySelectorAll('section > *:first-child'); - expect(headerElements[1].parentNode.hasAttribute('expanded')).to.be - .true; - expect(headerElements[1].getAttribute('aria-expanded')).to.equal( - 'true' - ); - impl.toggle_(headerElements[1].parentNode, ActionTrust.HIGH, false); - expect(headerElements[1].parentNode.hasAttribute('expanded')).to.be - .false; - expect(headerElements[1].getAttribute('aria-expanded')).to.equal( - 'false' - ); - }); + it('should collapse on the collapse action when expanded', async () => { + const ampAccordion = await getAmpAccordion(); + const impl = await ampAccordion.getImpl(); + const headerElements = doc.querySelectorAll('section > *:first-child'); + expect(headerElements[1].parentNode.hasAttribute('expanded')).to.be.true; + expect(headerElements[1].getAttribute('aria-expanded')).to.equal('true'); + impl.toggle_(headerElements[1].parentNode, ActionTrust.HIGH, false); + expect(headerElements[1].parentNode.hasAttribute('expanded')).to.be.false; + expect(headerElements[1].getAttribute('aria-expanded')).to.equal('false'); }); - it('should stay collapsed on the collapse action when collapsed', () => { - return getAmpAccordion().then((ampAccordion) => { - const impl = ampAccordion.implementation_; - const headerElements = doc.querySelectorAll('section > *:first-child'); - expect(headerElements[0].parentNode.hasAttribute('expanded')).to.be - .false; - expect(headerElements[0].getAttribute('aria-expanded')).to.equal( - 'false' - ); - impl.toggle_(headerElements[0].parentNode, ActionTrust.HIGH, false); - expect(headerElements[0].parentNode.hasAttribute('expanded')).to.be - .false; - expect(headerElements[0].getAttribute('aria-expanded')).to.equal( - 'false' - ); - }); + it('should stay collapsed on the collapse action when collapsed', async () => { + const ampAccordion = await getAmpAccordion(); + const impl = await ampAccordion.getImpl(); + const headerElements = doc.querySelectorAll('section > *:first-child'); + expect(headerElements[0].parentNode.hasAttribute('expanded')).to.be.false; + expect(headerElements[0].getAttribute('aria-expanded')).to.equal('false'); + impl.toggle_(headerElements[0].parentNode, ActionTrust.HIGH, false); + expect(headerElements[0].parentNode.hasAttribute('expanded')).to.be.false; + expect(headerElements[0].getAttribute('aria-expanded')).to.equal('false'); + }); + + it('should expand when header of a collapsed section is clicked', async () => { + const ampAccordion = await getAmpAccordion(); + const impl = await ampAccordion.getImpl(); + const headerElements = doc.querySelectorAll('section > *:first-child'); + const clickEvent = { + target: headerElements[0], + currentTarget: headerElements[0], + preventDefault: env.sandbox.spy(), + }; + expect(headerElements[0].parentNode.hasAttribute('expanded')).to.be.false; + expect(headerElements[0].getAttribute('aria-expanded')).to.equal('false'); + impl.onHeaderPicked_(clickEvent); + expect(headerElements[0].parentNode.hasAttribute('expanded')).to.be.true; + expect(headerElements[0].getAttribute('aria-expanded')).to.equal('true'); + expect(clickEvent.preventDefault.called).to.be.true; + }); + + it("should expand section when header's child is clicked", async () => { + const ampAccordion = await getAmpAccordion(); + const impl = await ampAccordion.getImpl(); + const headerElements = doc.querySelectorAll('section > *:first-child'); + const header = headerElements[0]; + const child = doc.createElement('div'); + header.appendChild(child); + const clickEvent = { + target: child, + currentTarget: header, + preventDefault: env.sandbox.spy(), + }; + expect(header.parentNode.hasAttribute('expanded')).to.be.false; + expect(header.getAttribute('aria-expanded')).to.equal('false'); + impl.onHeaderPicked_(clickEvent); + expect(header.parentNode.hasAttribute('expanded')).to.be.true; + expect(header.getAttribute('aria-expanded')).to.equal('true'); + expect(clickEvent.preventDefault).to.have.been.called; + }); + + it('should collapse when header of an expanded section is clicked', async () => { + const ampAccordion = await getAmpAccordion(); + const impl = await ampAccordion.getImpl(); + const headerElements = doc.querySelectorAll('section > *:first-child'); + const clickEvent = { + target: headerElements[1], + currentTarget: headerElements[1], + preventDefault: env.sandbox.spy(), + }; + expect(headerElements[1].parentNode.hasAttribute('expanded')).to.be.true; + expect(headerElements[1].getAttribute('aria-expanded')).to.equal('true'); + impl.onHeaderPicked_(clickEvent); + expect(headerElements[1].parentNode.hasAttribute('expanded')).to.be.false; + expect(headerElements[1].getAttribute('aria-expanded')).to.equal('false'); + expect(clickEvent.preventDefault).to.have.been.called; }); - it('should expand when header of a collapsed section is clicked', () => { - return getAmpAccordion().then((ampAccordion) => { + it('should allow for clickable links in header', async () => { + const ampAccordion = await getAmpAccordion(); + const impl = await ampAccordion.getImpl(); + const headerElements = doc.querySelectorAll('section > *:first-child'); + const a = doc.createElement('a'); + headerElements[0].appendChild(a); + const aClickEvent = { + target: a, + currentTarget: headerElements[0], + preventDefault: env.sandbox.spy(), + }; + impl.clickHandler_(aClickEvent); + expect(aClickEvent.preventDefault).to.not.have.been.called; + }); + + it( + 'should expand when header of a collapsed section is ' + + 'activated via keyboard', + async () => { + const ampAccordion = await getAmpAccordion(); + const impl = await ampAccordion.getImpl(); const headerElements = doc.querySelectorAll('section > *:first-child'); - const clickEvent = { + const keyDownEvent = { + key: Keys.SPACE, target: headerElements[0], currentTarget: headerElements[0], preventDefault: env.sandbox.spy(), @@ -489,40 +488,55 @@ describes.realWin( expect(headerElements[0].getAttribute('aria-expanded')).to.equal( 'false' ); - ampAccordion.implementation_.onHeaderPicked_(clickEvent); + impl.keyDownHandler_(keyDownEvent); expect(headerElements[0].parentNode.hasAttribute('expanded')).to.be .true; expect(headerElements[0].getAttribute('aria-expanded')).to.equal( 'true' ); - expect(clickEvent.preventDefault.called).to.be.true; - }); - }); + expect(keyDownEvent.preventDefault.called).to.be.true; + } + ); - it("should expand section when header's child is clicked", () => { - return getAmpAccordion().then((ampAccordion) => { + it( + "should NOT expand section when header's child is " + + 'activated via keyboard', + async () => { + const ampAccordion = await getAmpAccordion(); + const impl = await ampAccordion.getImpl(); const headerElements = doc.querySelectorAll('section > *:first-child'); - const header = headerElements[0]; const child = doc.createElement('div'); - header.appendChild(child); - const clickEvent = { + headerElements[0].appendChild(child); + const keyDownEvent = { + key: Keys.ENTER, target: child, - currentTarget: header, + currentTarget: headerElements[0], preventDefault: env.sandbox.spy(), }; - expect(header.parentNode.hasAttribute('expanded')).to.be.false; - expect(header.getAttribute('aria-expanded')).to.equal('false'); - ampAccordion.implementation_.onHeaderPicked_(clickEvent); - expect(header.parentNode.hasAttribute('expanded')).to.be.true; - expect(header.getAttribute('aria-expanded')).to.equal('true'); - expect(clickEvent.preventDefault).to.have.been.called; - }); - }); + expect(headerElements[0].parentNode.hasAttribute('expanded')).to.be + .false; + expect(headerElements[0].getAttribute('aria-expanded')).to.equal( + 'false' + ); + impl.keyDownHandler_(keyDownEvent); + expect(headerElements[0].parentNode.hasAttribute('expanded')).to.be + .false; + expect(headerElements[0].getAttribute('aria-expanded')).to.equal( + 'false' + ); + expect(keyDownEvent.preventDefault.called).to.be.false; + } + ); - it('should collapse when header of an expanded section is clicked', () => { - return getAmpAccordion().then((ampAccordion) => { + it( + 'should collapse when header of an expanded section is ' + + 'activated via keyboard', + async () => { + const ampAccordion = await getAmpAccordion(); + const impl = await ampAccordion.getImpl(); const headerElements = doc.querySelectorAll('section > *:first-child'); - const clickEvent = { + const keyDownEvent = { + key: Keys.ENTER, target: headerElements[1], currentTarget: headerElements[1], preventDefault: env.sandbox.spy(), @@ -532,403 +546,261 @@ describes.realWin( expect(headerElements[1].getAttribute('aria-expanded')).to.equal( 'true' ); - ampAccordion.implementation_.onHeaderPicked_(clickEvent); + impl.keyDownHandler_(keyDownEvent); expect(headerElements[1].parentNode.hasAttribute('expanded')).to.be .false; expect(headerElements[1].getAttribute('aria-expanded')).to.equal( 'false' ); - expect(clickEvent.preventDefault).to.have.been.called; - }); - }); - - it('should allow for clickable links in header', () => { - return getAmpAccordion().then((ampAccordion) => { - const headerElements = doc.querySelectorAll('section > *:first-child'); - const a = doc.createElement('a'); - headerElements[0].appendChild(a); - const aClickEvent = { - target: a, - currentTarget: headerElements[0], - preventDefault: env.sandbox.spy(), - }; - ampAccordion.implementation_.clickHandler_(aClickEvent); - expect(aClickEvent.preventDefault).to.not.have.been.called; - }); - }); - - it( - 'should expand when header of a collapsed section is ' + - 'activated via keyboard', - () => { - return getAmpAccordion().then((ampAccordion) => { - const headerElements = doc.querySelectorAll( - 'section > *:first-child' - ); - const keyDownEvent = { - key: Keys.SPACE, - target: headerElements[0], - currentTarget: headerElements[0], - preventDefault: env.sandbox.spy(), - }; - expect(headerElements[0].parentNode.hasAttribute('expanded')).to.be - .false; - expect(headerElements[0].getAttribute('aria-expanded')).to.equal( - 'false' - ); - ampAccordion.implementation_.keyDownHandler_(keyDownEvent); - expect(headerElements[0].parentNode.hasAttribute('expanded')).to.be - .true; - expect(headerElements[0].getAttribute('aria-expanded')).to.equal( - 'true' - ); - expect(keyDownEvent.preventDefault.called).to.be.true; - }); - } - ); - - it( - "should NOT expand section when header's child is " + - 'activated via keyboard', - () => { - return getAmpAccordion().then((ampAccordion) => { - const headerElements = doc.querySelectorAll( - 'section > *:first-child' - ); - const child = doc.createElement('div'); - headerElements[0].appendChild(child); - const keyDownEvent = { - key: Keys.ENTER, - target: child, - currentTarget: headerElements[0], - preventDefault: env.sandbox.spy(), - }; - expect(headerElements[0].parentNode.hasAttribute('expanded')).to.be - .false; - expect(headerElements[0].getAttribute('aria-expanded')).to.equal( - 'false' - ); - ampAccordion.implementation_.keyDownHandler_(keyDownEvent); - expect(headerElements[0].parentNode.hasAttribute('expanded')).to.be - .false; - expect(headerElements[0].getAttribute('aria-expanded')).to.equal( - 'false' - ); - expect(keyDownEvent.preventDefault.called).to.be.false; - }); - } - ); - - it( - 'should collapse when header of an expanded section is ' + - 'activated via keyboard', - () => { - return getAmpAccordion().then((ampAccordion) => { - const headerElements = doc.querySelectorAll( - 'section > *:first-child' - ); - const keyDownEvent = { - key: Keys.ENTER, - target: headerElements[1], - currentTarget: headerElements[1], - preventDefault: env.sandbox.spy(), - }; - expect(headerElements[1].parentNode.hasAttribute('expanded')).to.be - .true; - expect(headerElements[1].getAttribute('aria-expanded')).to.equal( - 'true' - ); - ampAccordion.implementation_.keyDownHandler_(keyDownEvent); - expect(headerElements[1].parentNode.hasAttribute('expanded')).to.be - .false; - expect(headerElements[1].getAttribute('aria-expanded')).to.equal( - 'false' - ); - expect(keyDownEvent.preventDefault.called).to.be.true; - }); + expect(keyDownEvent.preventDefault.called).to.be.true; } ); it( 'should be navigable by up and down arrow keys when ' + 'any header has focus', - () => { - return getAmpAccordion().then((ampAccordion) => { - const headerElements = doc.querySelectorAll( - 'section > *:first-child' - ); - // Focus the first header, - tryFocus(headerElements[0]); - expect(doc.activeElement).to.equal(headerElements[0]); - const upArrowEvent = { - key: Keys.UP_ARROW, - target: headerElements[0], - currentTarget: headerElements[0], - preventDefault: env.sandbox.spy(), - }; - ampAccordion.implementation_.keyDownHandler_(upArrowEvent); - expect(doc.activeElement).to.equal( - headerElements[headerElements.length - 1] - ); - const downArrowEvent = { - key: Keys.DOWN_ARROW, - target: headerElements[headerElements.length - 1], - currentTarget: headerElements[headerElements.length - 1], - preventDefault: env.sandbox.spy(), - }; - ampAccordion.implementation_.keyDownHandler_(downArrowEvent); - expect(doc.activeElement).to.equal(headerElements[0]); - }); - } - ); - - it('should return correct sessionStorageKey', () => { - return getAmpAccordion().then((ampAccordion) => { - const impl = ampAccordion.implementation_; - const url = win.location.href; - impl.element.id = '321'; - const id = impl.getSessionStorageKey_(); - const correctId = 'amp-321-' + url; - expect(id).to.be.equal(correctId); - }); - }); - - it('should set sessionStorage on change in expansion', () => { - return getAmpAccordion().then((ampAccordion) => { - const impl = ampAccordion.implementation_; + async () => { + const ampAccordion = await getAmpAccordion(); + const impl = await ampAccordion.getImpl(); const headerElements = doc.querySelectorAll('section > *:first-child'); - const clickEventExpandElement = { + // Focus the first header, + tryFocus(headerElements[0]); + expect(doc.activeElement).to.equal(headerElements[0]); + const upArrowEvent = { + key: Keys.UP_ARROW, target: headerElements[0], currentTarget: headerElements[0], preventDefault: env.sandbox.spy(), }; - const clickEventCollapseElement = { - target: headerElements[1], - currentTarget: headerElements[1], + impl.keyDownHandler_(upArrowEvent); + expect(doc.activeElement).to.equal( + headerElements[headerElements.length - 1] + ); + const downArrowEvent = { + key: Keys.DOWN_ARROW, + target: headerElements[headerElements.length - 1], + currentTarget: headerElements[headerElements.length - 1], preventDefault: env.sandbox.spy(), }; - expect(Object.keys(impl.currentState_)).to.have.length(0); - impl.onHeaderPicked_(clickEventExpandElement); - expect(Object.keys(impl.currentState_)).to.have.length(1); - expect(impl.currentState_['test0']).to.be.true; - impl.onHeaderPicked_(clickEventCollapseElement); - expect(Object.keys(impl.currentState_)).to.have.length(2); - expect(impl.currentState_['test0']).to.be.true; - expect(impl.currentState_['test1']).to.be.false; - }); + impl.keyDownHandler_(downArrowEvent); + expect(doc.activeElement).to.equal(headerElements[0]); + } + ); + + it('should return correct sessionStorageKey', async () => { + const ampAccordion = await getAmpAccordion(); + const impl = await ampAccordion.getImpl(); + const url = win.location.href; + impl.element.id = '321'; + const id = impl.getSessionStorageKey_(); + const correctId = 'amp-321-' + url; + expect(id).to.be.equal(correctId); }); - it('should respect session states and expand/collapse', () => { - return getAmpAccordion().then((ampAccordion) => { - const impl = ampAccordion.implementation_; - let headerElements = doc.querySelectorAll('section > *:first-child'); - expect(headerElements[0].parentNode.hasAttribute('expanded')).to.be - .false; - expect(headerElements[0].getAttribute('aria-expanded')).to.equal( - 'false' - ); - expect(headerElements[1].parentNode.hasAttribute('expanded')).to.be - .true; - expect(headerElements[2].parentNode.hasAttribute('expanded')).to.be - .false; - impl.getSessionState_ = function () { - return { - 'test0': true, - }; - }; - impl.buildCallback(); - headerElements = doc.querySelectorAll('section > *:first-child'); - expect(headerElements[0].parentNode.hasAttribute('expanded')).to.be - .true; - expect(headerElements[0].getAttribute('aria-expanded')).to.equal( - 'true' - ); - expect(headerElements[1].parentNode.hasAttribute('expanded')).to.be - .true; - expect(headerElements[2].parentNode.hasAttribute('expanded')).to.be - .false; - impl.getSessionState_ = function () { - return { - 'test0': true, - 'test1': false, - }; - }; - impl.buildCallback(); - headerElements = doc.querySelectorAll('section > *:first-child'); - expect(headerElements[0].parentNode.hasAttribute('expanded')).to.be - .true; - expect(headerElements[0].getAttribute('aria-expanded')).to.equal( - 'true' - ); - expect(headerElements[1].parentNode.hasAttribute('expanded')).to.be - .false; - expect(headerElements[2].parentNode.hasAttribute('expanded')).to.be - .false; - }); + it('should set sessionStorage on change in expansion', async () => { + const ampAccordion = await getAmpAccordion(); + const impl = await ampAccordion.getImpl(); + const headerElements = doc.querySelectorAll('section > *:first-child'); + const clickEventExpandElement = { + target: headerElements[0], + currentTarget: headerElements[0], + preventDefault: env.sandbox.spy(), + }; + const clickEventCollapseElement = { + target: headerElements[1], + currentTarget: headerElements[1], + preventDefault: env.sandbox.spy(), + }; + expect(Object.keys(impl.currentState_)).to.have.length(0); + impl.onHeaderPicked_(clickEventExpandElement); + expect(Object.keys(impl.currentState_)).to.have.length(1); + expect(impl.currentState_['test0']).to.be.true; + impl.onHeaderPicked_(clickEventCollapseElement); + expect(Object.keys(impl.currentState_)).to.have.length(2); + expect(impl.currentState_['test0']).to.be.true; + expect(impl.currentState_['test1']).to.be.false; }); - it('should disable sessionStorage when opt-out', () => { - return getAmpAccordion().then((ampAccordion) => { - const impl = ampAccordion.implementation_; - const setSessionStateSpy = env.sandbox.spy(); - const getSessionStateSpy = env.sandbox.spy(); - impl.win.sessionStorage.setItem = function () { - setSessionStateSpy(); + it('should respect session states and expand/collapse', async () => { + const ampAccordion = await getAmpAccordion(); + const impl = await ampAccordion.getImpl(); + let headerElements = doc.querySelectorAll('section > *:first-child'); + expect(headerElements[0].parentNode.hasAttribute('expanded')).to.be.false; + expect(headerElements[0].getAttribute('aria-expanded')).to.equal('false'); + expect(headerElements[1].parentNode.hasAttribute('expanded')).to.be.true; + expect(headerElements[2].parentNode.hasAttribute('expanded')).to.be.false; + impl.getSessionState_ = function () { + return { + 'test0': true, }; - impl.win.sessionStorage.getItem = function () { - getSessionStateSpy(); + }; + impl.buildCallback(); + headerElements = doc.querySelectorAll('section > *:first-child'); + expect(headerElements[0].parentNode.hasAttribute('expanded')).to.be.true; + expect(headerElements[0].getAttribute('aria-expanded')).to.equal('true'); + expect(headerElements[1].parentNode.hasAttribute('expanded')).to.be.true; + expect(headerElements[2].parentNode.hasAttribute('expanded')).to.be.false; + impl.getSessionState_ = function () { + return { + 'test0': true, + 'test1': false, }; + }; + impl.buildCallback(); + headerElements = doc.querySelectorAll('section > *:first-child'); + expect(headerElements[0].parentNode.hasAttribute('expanded')).to.be.true; + expect(headerElements[0].getAttribute('aria-expanded')).to.equal('true'); + expect(headerElements[1].parentNode.hasAttribute('expanded')).to.be.false; + expect(headerElements[2].parentNode.hasAttribute('expanded')).to.be.false; + }); - ampAccordion.setAttribute('disable-session-states', null); - impl.buildCallback(); - expect(Object.keys(impl.currentState_)).to.have.length(0); - const headerElements = doc.querySelectorAll('section > *:first-child'); - const clickEventExpandElement = { - target: headerElements[0], - currentTarget: headerElements[0], - preventDefault: env.sandbox.spy(), - }; - impl.onHeaderPicked_(clickEventExpandElement); - expect(getSessionStateSpy).to.not.have.been.called; - expect(setSessionStateSpy).to.not.have.been.called; - expect(Object.keys(impl.currentState_)).to.have.length(1); - }); + it('should disable sessionStorage when opt-out', async () => { + const ampAccordion = await getAmpAccordion(); + const impl = await ampAccordion.getImpl(); + const setSessionStateSpy = env.sandbox.spy(); + const getSessionStateSpy = env.sandbox.spy(); + impl.win.sessionStorage.setItem = function () { + setSessionStateSpy(); + }; + impl.win.sessionStorage.getItem = function () { + getSessionStateSpy(); + }; + + ampAccordion.setAttribute('disable-session-states', null); + impl.buildCallback(); + expect(Object.keys(impl.currentState_)).to.have.length(0); + const headerElements = doc.querySelectorAll('section > *:first-child'); + const clickEventExpandElement = { + target: headerElements[0], + currentTarget: headerElements[0], + preventDefault: env.sandbox.spy(), + }; + impl.onHeaderPicked_(clickEventExpandElement); + expect(getSessionStateSpy).to.not.have.been.called; + expect(setSessionStateSpy).to.not.have.been.called; + expect(Object.keys(impl.currentState_)).to.have.length(1); }); - it('two accordions should not affect each other', () => { - return getAmpAccordion().then((ampAccordion) => { - const ampAccordion1 = ampAccordion; - const ampAccordion2 = doc.createElement('amp-accordion'); - for (let i = 0; i < 3; i++) { - const section = doc.createElement('section'); - section.innerHTML = - '

Section ' + - i + - "nested stuff

Loreum ipsum
"; - ampAccordion2.appendChild(section); - } - doc.body.appendChild(ampAccordion2); - return ampAccordion2 - .build() - .then(() => { - ampAccordion.implementation_.mutateElement = (fn) => fn(); - return ampAccordion.layoutCallback(); - }) - .then(() => { - const headerElements1 = ampAccordion1.querySelectorAll( - 'section > *:first-child' - ); - const clickEventElement = { - target: headerElements1[0], - currentTarget: headerElements1[0], - preventDefault: env.sandbox.spy(), - }; - ampAccordion1.implementation_.onHeaderPicked_(clickEventElement); - const headerElements2 = ampAccordion2.querySelectorAll( - 'section > *:first-child' - ); - expect(headerElements1[0].parentNode.hasAttribute('expanded')).to.be - .true; - expect(headerElements2[0].parentNode.hasAttribute('expanded')).to.be - .false; - }); - }); + it('two accordions should not affect each other', async () => { + const ampAccordion = await getAmpAccordion(); + const impl = await ampAccordion.getImpl(); + const ampAccordion1 = ampAccordion; + const ampAccordion2 = doc.createElement('amp-accordion'); + for (let i = 0; i < 3; i++) { + const section = doc.createElement('section'); + section.innerHTML = + '

Section ' + + i + + "nested stuff

Loreum ipsum
"; + ampAccordion2.appendChild(section); + } + doc.body.appendChild(ampAccordion2); + await ampAccordion2.build(); + + impl.mutateElement = (fn) => fn(); + await ampAccordion.layoutCallback(); + + const headerElements1 = ampAccordion1.querySelectorAll( + 'section > *:first-child' + ); + const clickEventElement = { + target: headerElements1[0], + currentTarget: headerElements1[0], + preventDefault: env.sandbox.spy(), + }; + impl.onHeaderPicked_(clickEventElement); + const headerElements2 = ampAccordion2.querySelectorAll( + 'section > *:first-child' + ); + expect(headerElements1[0].parentNode.hasAttribute('expanded')).to.be.true; + expect(headerElements2[0].parentNode.hasAttribute('expanded')).to.be + .false; }); - it('should trigger expand/collapse events', () => { - return getAmpAccordion(true).then((ampAccordion) => { - const impl = ampAccordion.implementation_; + it('should trigger expand/collapse events', async () => { + const ampAccordion = await getAmpAccordion(true); + const impl = await ampAccordion.getImpl(); - const actions = impl.getActionServiceForTesting(); - env.sandbox.stub(actions, 'trigger'); + const actions = impl.getActionServiceForTesting(); + env.sandbox.stub(actions, 'trigger'); - execute(impl, 'collapse', 123, `acc${counter}sec1`); + execute(impl, 'collapse', 123, `acc${counter}sec1`); - expect(actions.trigger).to.be.calledOnce; - expect(actions.trigger.getCall(0)).to.be.calledWith( - /* element */ env.sandbox.match.has('tagName'), - 'collapse', - /* event */ env.sandbox.match.has('detail'), - /* trust */ 123 - ); + expect(actions.trigger).to.be.calledOnce; + expect(actions.trigger.getCall(0)).to.be.calledWith( + /* element */ env.sandbox.match.has('tagName'), + 'collapse', + /* event */ env.sandbox.match.has('detail'), + /* trust */ 123 + ); - execute(impl, 'expand', 456, `acc${counter}sec1`); + execute(impl, 'expand', 456, `acc${counter}sec1`); - expect(actions.trigger).to.be.calledTwice; - expect(actions.trigger.getCall(1)).to.be.calledWith( - /* element */ env.sandbox.match.has('tagName'), - 'expand', - /* event */ env.sandbox.match.has('detail'), - /* trust */ 456 - ); - }); + expect(actions.trigger).to.be.calledTwice; + expect(actions.trigger.getCall(1)).to.be.calledWith( + /* element */ env.sandbox.match.has('tagName'), + 'expand', + /* event */ env.sandbox.match.has('detail'), + /* trust */ 456 + ); }); - it('should include a11y related attributes', () => { - return getAmpAccordion().then(() => { - const sectionElements = doc.querySelectorAll('section'); - expect(sectionElements.length).to.equal(3); - - const section0 = sectionElements[0]; - const section1 = sectionElements[1]; - const section2 = sectionElements[2]; - const { - firstElementChild: header0, - lastElementChild: content0, - } = section0; - const { - firstElementChild: header1, - lastElementChild: content1, - } = section1; - const { - firstElementChild: header2, - lastElementChild: content2, - } = section2; - - expect(header0).to.have.attribute('id'); - expect(header0.getAttribute('aria-controls')).to.equal('test0'); - expect(header0.getAttribute('tabindex')).to.equal('0'); - expect(header0.getAttribute('role')).to.equal('button'); - expect(content0).to.have.attribute('aria-labelledby'); - expect(content0.getAttribute('id')).to.equal('test0'); - expect(content0.getAttribute('role')).to.equal('region'); - expect(header0.getAttribute('aria-controls')).to.equal( - content0.getAttribute('id') - ); - expect(header0.getAttribute('id')).to.equal( - content0.getAttribute('aria-labelledby') - ); + it('should include a11y related attributes', async () => { + await getAmpAccordion(); + + const sectionElements = doc.querySelectorAll('section'); + expect(sectionElements.length).to.equal(3); + + const section0 = sectionElements[0]; + const section1 = sectionElements[1]; + const section2 = sectionElements[2]; + const {firstElementChild: header0, lastElementChild: content0} = section0; + const {firstElementChild: header1, lastElementChild: content1} = section1; + const {firstElementChild: header2, lastElementChild: content2} = section2; + + expect(header0).to.have.attribute('id'); + expect(header0.getAttribute('aria-controls')).to.equal('test0'); + expect(header0.getAttribute('tabindex')).to.equal('0'); + expect(header0.getAttribute('role')).to.equal('button'); + expect(content0).to.have.attribute('aria-labelledby'); + expect(content0.getAttribute('id')).to.equal('test0'); + expect(content0.getAttribute('role')).to.equal('region'); + expect(header0.getAttribute('aria-controls')).to.equal( + content0.getAttribute('id') + ); + expect(header0.getAttribute('id')).to.equal( + content0.getAttribute('aria-labelledby') + ); - expect(header1).to.have.attribute('id'); - expect(header1.getAttribute('aria-controls')).to.equal('test1'); - expect(header1.getAttribute('tabindex')).to.equal('0'); - expect(header1.getAttribute('role')).to.equal('button'); - expect(content1).to.have.attribute('aria-labelledby'); - expect(content1.getAttribute('id')).to.equal('test1'); - expect(content1.getAttribute('role')).to.equal('region'); - expect(header1.getAttribute('aria-controls')).to.equal( - content1.getAttribute('id') - ); - expect(header1.getAttribute('id')).to.equal( - content1.getAttribute('aria-labelledby') - ); + expect(header1).to.have.attribute('id'); + expect(header1.getAttribute('aria-controls')).to.equal('test1'); + expect(header1.getAttribute('tabindex')).to.equal('0'); + expect(header1.getAttribute('role')).to.equal('button'); + expect(content1).to.have.attribute('aria-labelledby'); + expect(content1.getAttribute('id')).to.equal('test1'); + expect(content1.getAttribute('role')).to.equal('region'); + expect(header1.getAttribute('aria-controls')).to.equal( + content1.getAttribute('id') + ); + expect(header1.getAttribute('id')).to.equal( + content1.getAttribute('aria-labelledby') + ); - expect(header2).to.have.attribute('id'); - expect(header2.getAttribute('aria-controls')).to.equal('test2'); - expect(header2.getAttribute('tabindex')).to.equal('0'); - expect(header2.getAttribute('role')).to.equal('button'); - expect(content2).to.have.attribute('aria-labelledby'); - expect(content2.getAttribute('id')).to.equal('test2'); - expect(content2.getAttribute('role')).to.equal('region'); - expect(header2.getAttribute('aria-controls')).to.equal( - content2.getAttribute('id') - ); - expect(header2.getAttribute('id')).to.equal( - content2.getAttribute('aria-labelledby') - ); - }); + expect(header2).to.have.attribute('id'); + expect(header2.getAttribute('aria-controls')).to.equal('test2'); + expect(header2.getAttribute('tabindex')).to.equal('0'); + expect(header2.getAttribute('role')).to.equal('button'); + expect(content2).to.have.attribute('aria-labelledby'); + expect(content2.getAttribute('id')).to.equal('test2'); + expect(content2.getAttribute('role')).to.equal('region'); + expect(header2.getAttribute('aria-controls')).to.equal( + content2.getAttribute('id') + ); + expect(header2.getAttribute('id')).to.equal( + content2.getAttribute('aria-labelledby') + ); }); } ); diff --git a/extensions/amp-ad-exit/0.1/test/test-amp-ad-exit.js b/extensions/amp-ad-exit/0.1/test/test-amp-ad-exit.js index ebc4da0b4598..094e6632063c 100644 --- a/extensions/amp-ad-exit/0.1/test/test-amp-ad-exit.js +++ b/extensions/amp-ad-exit/0.1/test/test-amp-ad-exit.js @@ -175,16 +175,18 @@ describes.realWin( win.document.body.appendChild(adDiv); } - function pointTo(target) { - element.implementation_.executeAction({ + async function pointTo(target) { + const impl = await element.getImpl(); + impl.executeAction({ method: 'setVariable', args: {name: 'indirect', target}, satisfiesTrust: () => true, }); } - function exitIndirect() { - element.implementation_.executeAction({ + async function exitIndirect() { + const impl = await element.getImpl(); + impl.executeAction({ method: 'exit', args: {variable: 'indirect', default: 'simple'}, event: makeClickEvent(1001), @@ -222,11 +224,12 @@ describes.realWin( return promise.should.be.rejectedWith(/application\/json/); }); - it('should do nothing for missing targets', () => { + it('should do nothing for missing targets', async () => { const open = env.sandbox.stub(win, 'open'); + const impl = await element.getImpl(); try { allowConsoleError(() => - element.implementation_.executeAction({ + impl.executeAction({ method: 'exit', args: {target: 'not-a-real-target'}, event: makeClickEvent(1001), @@ -237,9 +240,10 @@ describes.realWin( } catch (expected) {} }); - it('should stop event propagation', () => { + it('should stop event propagation', async () => { const event = makeClickEvent(1001); - element.implementation_.executeAction({ + const impl = await element.getImpl(); + impl.executeAction({ method: 'exit', args: {target: 'twoSecondDelay'}, event, @@ -248,17 +252,18 @@ describes.realWin( expect(event.preventDefault).to.have.been.called; }); - it('should reject fast clicks', () => { + it('should reject fast clicks', async () => { const open = env.sandbox.stub(win, 'open'); + const impl = await element.getImpl(); - element.implementation_.executeAction({ + impl.executeAction({ method: 'exit', args: {target: 'simple'}, event: makeClickEvent(999), satisfiesTrust: () => true, }); - element.implementation_.executeAction({ + impl.executeAction({ method: 'exit', args: {target: 'twoSecondDelay'}, event: makeClickEvent(1000), // 1000 ms + 999 from the previous exit. @@ -268,8 +273,8 @@ describes.realWin( expect(open).to.not.have.been.called; }); - it('should use options.startTimingEvent', () => { - return makeElementWithConfig({ + it('should use options.startTimingEvent', async () => { + const el = await makeElementWithConfig({ targets: { navStart: { 'finalUrl': 'http://localhost:8000/simple', @@ -283,24 +288,25 @@ describes.realWin( delay: 2000, }, }, - }).then((el) => { - expect(el.implementation_.defaultFilters_.length).to.equal(2); - let clickFilter = el.implementation_.defaultFilters_[0]; - expect(clickFilter.spec.type).to.equal(FilterType.CLICK_DELAY); - expect(clickFilter.spec.startTimingEvent).to.equal('navigationStart'); - clickFilter = el.implementation_.userFilters_['twoSecond']; - expect(clickFilter).to.be.ok; - expect(clickFilter.spec.type).to.equal(FilterType.CLICK_DELAY); - expect(clickFilter.spec.startTimingEvent).to.equal('navigationStart'); }); + const impl = await el.getImpl(); + expect(impl.defaultFilters_.length).to.equal(2); + let clickFilter = impl.defaultFilters_[0]; + expect(clickFilter.spec.type).to.equal(FilterType.CLICK_DELAY); + expect(clickFilter.spec.startTimingEvent).to.equal('navigationStart'); + clickFilter = impl.userFilters_['twoSecond']; + expect(clickFilter).to.be.ok; + expect(clickFilter.spec.type).to.equal(FilterType.CLICK_DELAY); + expect(clickFilter.spec.startTimingEvent).to.equal('navigationStart'); }); - it('should attempt new-tab navigation', () => { + it('should attempt new-tab navigation', async () => { const open = env.sandbox.stub(win, 'open').callsFake(() => { return {name: 'fakeWin'}; }); + const impl = await element.getImpl(); - element.implementation_.executeAction({ + impl.executeAction({ method: 'exit', args: {target: 'simple'}, event: makeClickEvent(1001), @@ -314,10 +320,11 @@ describes.realWin( ); }); - it('should fall back to top navigation', () => { + it('should fall back to top navigation', async () => { const open = env.sandbox.stub(win, 'open').callsFake(() => null); + const impl = await element.getImpl(); - element.implementation_.executeAction({ + impl.executeAction({ method: 'exit', args: {target: 'simple'}, event: makeClickEvent(1001), @@ -335,12 +342,13 @@ describes.realWin( ); }); - it('should attempt same-tab navigation', () => { + it('should attempt same-tab navigation', async () => { const open = env.sandbox.stub(win, 'open').callsFake(() => { return {name: 'fakeWin'}; }); + const impl = await element.getImpl(); - element.implementation_.executeAction({ + impl.executeAction({ method: 'exit', args: {target: 'clickTargetTest'}, event: makeClickEvent(1001), @@ -354,15 +362,16 @@ describes.realWin( ); }); - it('should ping tracking URLs with sendBeacon', () => { + it('should ping tracking URLs with sendBeacon', async () => { const open = env.sandbox.stub(win, 'open').callsFake(() => { return {name: 'fakeWin'}; }); const sendBeacon = env.sandbox .stub(win.navigator, 'sendBeacon') .callsFake(() => true); + const impl = await element.getImpl(); - element.implementation_.executeAction({ + impl.executeAction({ method: 'exit', args: {target: 'tracking'}, event: makeClickEvent(1001), @@ -385,10 +394,11 @@ describes.realWin( ); }); - it('should ping tracking URLs with image requests (no sendBeacon)', () => { + it('should ping tracking URLs with image requests (no sendBeacon)', async () => { const open = env.sandbox.stub(win, 'open').callsFake(() => { return {name: 'fakeWin'}; }); + const impl = await element.getImpl(); let sendBeacon; if (win.navigator.sendBeacon) { @@ -399,7 +409,7 @@ describes.realWin( const {createElement} = win.document; createElement.resetHistory(); - element.implementation_.executeAction({ + impl.executeAction({ method: 'exit', args: {target: 'tracking'}, event: makeClickEvent(1001), @@ -418,10 +428,11 @@ describes.realWin( } }); - it('should ping tracking URLs with image requests (sendBeacon fails)', () => { + it('should ping tracking URLs with image requests (sendBeacon fails)', async () => { const open = env.sandbox.stub(win, 'open').callsFake(() => { return {name: 'fakeWin'}; }); + const impl = await element.getImpl(); const sendBeacon = env.sandbox .stub(win.navigator, 'sendBeacon') @@ -429,7 +440,7 @@ describes.realWin( const {createElement} = win.document; createElement.resetHistory(); - element.implementation_.executeAction({ + impl.executeAction({ method: 'exit', args: {target: 'tracking'}, event: makeClickEvent(1001), @@ -445,7 +456,7 @@ describes.realWin( expect(imgs[2].src).to.equal('http://localhost:8000/tracking?3'); }); - it('should ping tracking URLs with image requests (transport)', () => { + it('should ping tracking URLs with image requests (transport)', async () => { const config = { targets: EXIT_CONFIG.targets, filters: EXIT_CONFIG.filters, @@ -453,38 +464,39 @@ describes.realWin( beacon: false, }, }; - return makeElementWithConfig(config).then((el) => { - const open = env.sandbox.stub(win, 'open').callsFake(() => { - return {name: 'fakeWin'}; - }); + const el = await makeElementWithConfig(config); + const impl = await el.getImpl(); + const open = env.sandbox.stub(win, 'open').callsFake(() => { + return {name: 'fakeWin'}; + }); - const sendBeacon = env.sandbox - .stub(win.navigator, 'sendBeacon') - .callsFake(() => true); - const {createElement} = win.document; - createElement.resetHistory(); - - el.implementation_.executeAction({ - method: 'exit', - args: {target: 'tracking'}, - event: makeClickEvent(1001), - satisfiesTrust: () => true, - }); + const sendBeacon = env.sandbox + .stub(win.navigator, 'sendBeacon') + .callsFake(() => true); + const {createElement} = win.document; + createElement.resetHistory(); - expect(open).to.have.been.calledOnce; - expect(sendBeacon).to.not.have.been.called; - expect(createElement.withArgs('img')).to.have.been.calledThrice; - const imgs = createElement.withArgs('img').returnValues; - expect(imgs[0].src).to.equal('http://localhost:8000/tracking?1'); - expect(imgs[1].src).to.equal('http://localhost:8000/tracking?2'); - expect(imgs[2].src).to.equal('http://localhost:8000/tracking?3'); + impl.executeAction({ + method: 'exit', + args: {target: 'tracking'}, + event: makeClickEvent(1001), + satisfiesTrust: () => true, }); + + expect(open).to.have.been.calledOnce; + expect(sendBeacon).to.not.have.been.called; + expect(createElement.withArgs('img')).to.have.been.calledThrice; + const imgs = createElement.withArgs('img').returnValues; + expect(imgs[0].src).to.equal('http://localhost:8000/tracking?1'); + expect(imgs[1].src).to.equal('http://localhost:8000/tracking?2'); + expect(imgs[2].src).to.equal('http://localhost:8000/tracking?3'); }); - it('should replace standard URL variables', () => { + it('should replace standard URL variables', async () => { const open = env.sandbox.stub(win, 'open').callsFake(() => { return {name: 'fakeWin'}; }); + const impl = await element.getImpl(); if (!win.navigator) { win.navigator = {sendBeacon: () => false}; @@ -493,7 +505,7 @@ describes.realWin( .stub(win.navigator, 'sendBeacon') .callsFake(() => true); - element.implementation_.executeAction({ + impl.executeAction({ method: 'exit', args: {target: 'variables'}, event: makeClickEvent(1001, 101, 102), @@ -514,10 +526,11 @@ describes.realWin( expect(sendBeacon).to.have.been.calledWith(trackingMatcher, ''); }); - it('should replace custom URL variables with vars', () => { + it('should replace custom URL variables with vars', async () => { const open = env.sandbox.stub(win, 'open').callsFake(() => { return {name: 'fakeWin'}; }); + const impl = await element.getImpl(); if (!win.navigator) { win.navigator = {sendBeacon: () => false}; @@ -526,7 +539,7 @@ describes.realWin( .stub(win.navigator, 'sendBeacon') .callsFake(() => true); - element.implementation_.executeAction({ + impl.executeAction({ method: 'exit', args: { target: 'customVars', @@ -553,21 +566,22 @@ describes.realWin( ); }); - it('border protection', () => { + it('border protection', async () => { const open = env.sandbox.stub(win, 'open').callsFake(() => { return {name: 'fakeWin'}; }); + const impl = await element.getImpl(); win.innerWidth = 1000; win.innerHeight = 2000; // Replace the getVsync function so that the measure can happen at once. - element.implementation_.getVsync = () => { + impl.getVsync = () => { return {measure: (callback) => callback()}; }; - element.implementation_.onLayoutMeasure(); + impl.onLayoutMeasure(); // The click is within the top border. - element.implementation_.executeAction({ + impl.executeAction({ method: 'exit', args: {target: 'borderProtection'}, event: makeClickEvent(1001, 500, 8), @@ -575,7 +589,7 @@ describes.realWin( }); // The click is within the right border. - element.implementation_.executeAction({ + impl.executeAction({ method: 'exit', args: {target: 'borderProtection'}, event: makeClickEvent(1001, 993, 500), @@ -583,7 +597,7 @@ describes.realWin( }); // The click is within the bottom border. - element.implementation_.executeAction({ + impl.executeAction({ method: 'exit', args: {target: 'borderProtection'}, event: makeClickEvent(1001, 500, 1992), @@ -594,7 +608,7 @@ describes.realWin( // The click is within the left border but left border protection is not // set. - element.implementation_.executeAction({ + impl.executeAction({ method: 'exit', args: {target: 'borderProtection'}, event: makeClickEvent(1001, 8, 500), @@ -602,7 +616,7 @@ describes.realWin( }); // THe click is not within the border area. - element.implementation_.executeAction({ + impl.executeAction({ method: 'exit', args: {target: 'borderProtection'}, event: makeClickEvent(1001, 500, 500), @@ -615,19 +629,20 @@ describes.realWin( ); }); - it('border protection relative to div', () => { + it('border protection relative to div', async () => { const open = env.sandbox.stub(win, 'open').callsFake(() => { return {name: 'fakeWin'}; }); + const impl = await element.getImpl(); // Replace the getVsync function so that the measure can happen at once. - element.implementation_.getVsync = () => { + impl.getVsync = () => { return {measure: (callback) => callback()}; }; - element.implementation_.onLayoutMeasure(); + impl.onLayoutMeasure(); // The click is within the top border. - element.implementation_.executeAction({ + impl.executeAction({ method: 'exit', args: {target: 'borderProtectionRelativeTo'}, event: makeClickEvent(1001, 200, 208), @@ -635,7 +650,7 @@ describes.realWin( }); // The click is within the right border. - element.implementation_.executeAction({ + impl.executeAction({ method: 'exit', args: {target: 'borderProtectionRelativeTo'}, event: makeClickEvent(1001, 293, 300), @@ -643,7 +658,7 @@ describes.realWin( }); // The click is within the bottom border. - element.implementation_.executeAction({ + impl.executeAction({ method: 'exit', args: {target: 'borderProtectionRelativeTo'}, event: makeClickEvent(1001, 200, 392), @@ -654,7 +669,7 @@ describes.realWin( // The click is within the left border but left border protection is not // set. - element.implementation_.executeAction({ + impl.executeAction({ method: 'exit', args: {target: 'borderProtectionRelativeTo'}, event: makeClickEvent(1001, 103, 300), @@ -662,7 +677,7 @@ describes.realWin( }); // THe click is not within the border area. - element.implementation_.executeAction({ + impl.executeAction({ method: 'exit', args: {target: 'borderProtectionRelativeTo'}, event: makeClickEvent(1001, 200, 300), @@ -675,11 +690,12 @@ describes.realWin( ); }); - it('should not trigger for amp-carousel buttons', () => { + it('should not trigger for amp-carousel buttons', async () => { const open = env.sandbox.stub(win, 'open'); + const impl = await element.getImpl(); const fakeCarouselButton = document.createElement('div'); fakeCarouselButton.classList.add('amp-carousel-button'); - element.implementation_.executeAction({ + impl.executeAction({ method: 'exit', args: {target: 'simple'}, event: makeClickEvent(1001, 200, 300, fakeCarouselButton), @@ -688,18 +704,19 @@ describes.realWin( expect(open).to.not.have.been.called; }); - it('should not trigger for elements matching InactiveElementFilter', () => { + it('should not trigger for elements matching InactiveElementFilter', async () => { const open = env.sandbox.stub(win, 'open'); + const impl = await element.getImpl(); const unclickable = document.createElement('span'); unclickable.id = 'unclickable'; - element.implementation_.executeAction({ + impl.executeAction({ method: 'exit', args: {target: 'inactiveElementTest'}, event: makeClickEvent(1001, 200, 300, unclickable), satisfiesTrust: () => true, }); expect(open).to.not.have.been.called; - element.implementation_.executeAction({ + impl.executeAction({ method: 'exit', args: {target: 'inactiveElementTest'}, event: makeClickEvent(1001, 200, 300, win.document.body), @@ -708,10 +725,11 @@ describes.realWin( expect(open).to.have.been.called; }); - it('should replace custom URL variables with 3P Analytics defaults', () => { + it('should replace custom URL variables with 3P Analytics defaults', async () => { const open = env.sandbox.stub(win, 'open').returns({name: 'fakeWin'}); + const impl = await element.getImpl(); - element.implementation_.executeAction({ + impl.executeAction({ method: 'exit', args: {target: 'variableFrom3pAnalytics'}, event: makeClickEvent(1004), @@ -724,17 +742,18 @@ describes.realWin( ); }); - it('should replace custom URL variables with 3P Analytics signals', () => { + it('should replace custom URL variables with 3P Analytics signals', async () => { const open = env.sandbox.stub(win, 'open').callsFake(() => { return {name: 'fakeWin'}; }); + const impl = await element.getImpl(); - element.implementation_.vendorResponses_[TEST_3P_VENDOR] = { + impl.vendorResponses_[TEST_3P_VENDOR] = { 'unused': 'unused', 'collected-data': 'abc123', }; - element.implementation_.executeAction({ + impl.executeAction({ method: 'exit', args: {target: 'variableFrom3pAnalytics'}, event: makeClickEvent(1005), @@ -778,11 +797,11 @@ describes.realWin( ); }); - it('should exit to the default target if varible target is never set', () => { + it('should exit to the default target if varible target is never set', async () => { const open = env.sandbox.stub(win, 'open').callsFake(() => { return {name: 'fakeWin'}; }); - exitIndirect(); + await exitIndirect(); expect(open).to.have.been.calledOnce; expect(open).to.have.been.calledWith( EXIT_CONFIG.targets.simple.finalUrl, @@ -790,10 +809,11 @@ describes.realWin( ); }); - it('should cause error when variable target is never set and default value is not provided', () => { + it('should cause error when variable target is never set and default value is not provided', async () => { + const impl = await element.getImpl(); try { allowConsoleError(() => { - element.implementation_.executeAction({ + impl.executeAction({ method: 'exit', args: { variable: 'indirect', @@ -808,10 +828,15 @@ describes.realWin( expect.fail(); }); - it('should cause error when variable target was pointed to an invalid target', () => { + it('should cause error when variable target was pointed to an invalid target', async () => { + const impl = await element.getImpl(); try { allowConsoleError(() => { - pointTo('not-a-real-target'); + impl.executeAction({ + method: 'setVariable', + args: {name: 'indirect', target: 'not-a-real-target'}, + satisfiesTrust: () => true, + }); }); } catch (expected) { return; @@ -819,10 +844,11 @@ describes.realWin( expect.fail(); }); - it('should cause error when exiting to an invalid variable target', () => { + it('should cause error when exiting to an invalid variable target', async () => { + const impl = await element.getImpl(); try { allowConsoleError(() => { - element.implementation_.executeAction({ + impl.executeAction({ method: 'exit', args: {variable: 'not-a-real-target', default: 'not-a-real-target'}, event: makeClickEvent(1001), @@ -835,10 +861,11 @@ describes.realWin( expect.fail(); }); - it('should cause error when neither "target" nor "variable" is provided in arguments', () => { + it('should cause error when neither "target" nor "variable" is provided in arguments', async () => { + const impl = await element.getImpl(); try { allowConsoleError(() => { - element.implementation_.executeAction({ + impl.executeAction({ method: 'exit', args: {}, event: makeClickEvent(1001), @@ -851,10 +878,11 @@ describes.realWin( expect.fail(); }); - it('should cause error when both "target" and "variable" are provided in arguments', () => { + it('should cause error when both "target" and "variable" are provided in arguments', async () => { + const impl = await element.getImpl(); try { allowConsoleError(() => { - element.implementation_.executeAction({ + impl.executeAction({ method: 'exit', args: { target: 'customVars', @@ -871,10 +899,11 @@ describes.realWin( expect.fail(); }); - it('should exit to the pointed-to target and work with custom URL variables', () => { + it('should exit to the pointed-to target and work with custom URL variables', async () => { const open = env.sandbox.stub(win, 'open').callsFake(() => { return {name: 'fakeWin'}; }); + const impl = await element.getImpl(); if (!win.navigator) { win.navigator = {sendBeacon: () => false}; } @@ -882,16 +911,16 @@ describes.realWin( .stub(win.navigator, 'sendBeacon') .callsFake(() => true); - pointTo('clickTargetTest'); - exitIndirect(); + await pointTo('clickTargetTest'); + await exitIndirect(); expect(open).to.have.been.calledOnce; expect(open).to.have.been.calledWith( EXIT_CONFIG.targets.clickTargetTest.finalUrl, '_top' ); - pointTo('customVars'); - element.implementation_.executeAction({ + await pointTo('customVars'); + impl.executeAction({ method: 'exit', args: { variable: 'indirect', diff --git a/extensions/amp-addthis/0.1/test/test-amp-addthis.js b/extensions/amp-addthis/0.1/test/test-amp-addthis.js index 059cec6154e4..7c0090d6763f 100644 --- a/extensions/amp-addthis/0.1/test/test-amp-addthis.js +++ b/extensions/amp-addthis/0.1/test/test-amp-addthis.js @@ -196,14 +196,13 @@ describes.realWin( ).to.not.equal(void 0); }); - it('removes the iframe after unlayoutCallback', () => { - return getAT({pubId, widgetId}).then(({at}) => { - const obj = at.implementation_; - testIframe(at.querySelector('iframe')); - obj.unlayoutCallback(); - expect(at.querySelector('iframe')).to.equal(null); - expect(obj.iframe_).to.equal(null); - }); + it('removes the iframe after unlayoutCallback', async () => { + const {at} = await getAT({pubId, widgetId}); + const obj = await at.getImpl(); + testIframe(at.querySelector('iframe')); + obj.unlayoutCallback(); + expect(at.querySelector('iframe')).to.equal(null); + expect(obj.iframe_).to.equal(null); }); it('registers the frame with the configManager on layout', () => { @@ -212,13 +211,12 @@ describes.realWin( }); }); - it('unregisters the frame with the configManager on unlayoutCallback', () => { - return getAT({pubId, widgetId}).then(({at}) => { - const obj = at.implementation_; - obj.unlayoutCallback(); + it('unregisters the frame with the configManager on unlayoutCallback', async () => { + const {at} = await getAT({pubId, widgetId}); + const obj = await at.getImpl(); + obj.unlayoutCallback(); - expect(unregisterStub.calledOnce).to.equal(true); - }); + expect(unregisterStub.calledOnce).to.equal(true); }); it('accepts and stores shareConfig data via custom attributes', () => { @@ -239,13 +237,12 @@ describes.realWin( }); }); - it("defaults to sharing ownerDocument's title and url", () => { - return getAT({pubId, widgetId}).then(({at}) => { - const obj = at.implementation_; - const {shareConfig_} = obj; - expect(shareConfig_.title).to.equal(doc.title); - expect(shareConfig_.url).to.equal(doc.location.href); - }); + it("defaults to sharing ownerDocument's title and url", async () => { + const {at} = await getAT({pubId, widgetId}); + const obj = await at.getImpl(); + const {shareConfig_} = obj; + expect(shareConfig_.title).to.equal(doc.title); + expect(shareConfig_.url).to.equal(doc.location.href); }); it('registers a view at most once per "session"', (done) => { diff --git a/extensions/amp-animation/0.1/test/test-amp-animation.js b/extensions/amp-animation/0.1/test/test-amp-animation.js index 46fccce3651d..ee3d3167bb22 100644 --- a/extensions/amp-animation/0.1/test/test-amp-animation.js +++ b/extensions/amp-animation/0.1/test/test-amp-animation.js @@ -70,7 +70,7 @@ describes.sandboxed('AmpAnimation', {}, (env) => { } win.document.body.appendChild(element); - return element.build().then(() => element.implementation_); + return element.build().then(() => element.getImpl()); } function updateIntersection(target, intersectionRatio) { @@ -173,8 +173,8 @@ describes.sandboxed('AmpAnimation', {}, (env) => { ); }); - it('should update visibility from viewer', function* () { - const anim = yield createAnim({}, {duration: 1001}); + it('should update visibility from viewer', async () => { + const anim = await createAnim({}, {duration: 1001}); expect(anim.visible_).to.be.false; viewer.setVisibilityState_('visible'); diff --git a/extensions/amp-animation/0.1/test/test-web-animations.js b/extensions/amp-animation/0.1/test/test-web-animations.js index a85b72491577..96d7f80f9531 100644 --- a/extensions/amp-animation/0.1/test/test-web-animations.js +++ b/extensions/amp-animation/0.1/test/test-web-animations.js @@ -1064,8 +1064,9 @@ describes.realWin('MeasureScanner', {amp: 1}, (env) => { beforeEach(() => { animation2Spec = {}; animation2 = env.createAmpElement('amp-animation'); - animation2.implementation_.getAnimationSpec = () => animation2Spec; - animation2.signals().signal('built'); + env.sandbox.stub(animation2, 'getImpl').resolves({ + getAnimationSpec: () => animation2Spec, + }); animation2.id = 'animation2'; doc.body.appendChild(animation2); diff --git a/extensions/amp-apester-media/0.1/test/test-amp-apester-media.js b/extensions/amp-apester-media/0.1/test/test-amp-apester-media.js index 2ccdaf6be888..0e1678a7f6da 100644 --- a/extensions/amp-apester-media/0.1/test/test-amp-apester-media.js +++ b/extensions/amp-apester-media/0.1/test/test-amp-apester-media.js @@ -40,7 +40,7 @@ describes.realWin( } }); - function getApester(attributes, opt_responsive) { + async function getApester(attributes, opt_responsive) { const media = doc.createElement('amp-apester-media'); const regularResponse = { status: 200, @@ -81,14 +81,6 @@ describes.realWin( ? playlistResponse : regularResponse; - changeSizeSpy = env.sandbox.spy( - media.implementation_, - 'forceChangeHeight' - ); - attemptChangeSizeSpy = env.sandbox.spy( - media.implementation_, - 'attemptChangeHeight' - ); xhrMock = env.sandbox.mock(Services.xhrFor(win)); if (attributes) { xhrMock.expects('fetchJson').returns( @@ -112,12 +104,14 @@ describes.realWin( media.setAttribute('layout', 'responsive'); } doc.body.appendChild(media); - return media - .build() - .then(() => { - return media.layoutCallback(); - }) - .then(() => media); + await media.build(); + + const impl = await media.getImpl(); + changeSizeSpy = env.sandbox.spy(impl, 'forceChangeHeight'); + attemptChangeSizeSpy = env.sandbox.spy(impl, 'attemptChangeHeight'); + + await media.layoutCallback(); + return media; } it('renders', () => { @@ -186,21 +180,20 @@ describes.realWin( }); }); - it('removes iframe after unlayoutCallback', () => { - return getApester({ + it('removes iframe after unlayoutCallback', async () => { + const ape = await getApester({ 'data-apester-media-id': '5aaa70c79aaf0c5443078d31', - }).then((ape) => { - const iframe = ape.querySelector('iframe'); - expect(iframe).to.not.be.null; - expect(iframe.src).not.to.be.null; - const url = new URL(iframe.src); - expect(url.hostname).to.equal('renderer.apester.com'); - expect(url.pathname).to.equal('/interaction/5aaa70c79aaf0c5443078d31'); - const tag = ape.implementation_; - tag.unlayoutCallback(); - expect(ape.querySelector('iframe')).to.be.null; - expect(tag.iframe_).to.be.null; }); + const tag = await ape.getImpl(); + const iframe = ape.querySelector('iframe'); + expect(iframe).to.not.be.null; + expect(iframe.src).not.to.be.null; + const url = new URL(iframe.src); + expect(url.hostname).to.equal('renderer.apester.com'); + expect(url.pathname).to.equal('/interaction/5aaa70c79aaf0c5443078d31'); + tag.unlayoutCallback(); + expect(ape.querySelector('iframe')).to.be.null; + expect(tag.iframe_).to.be.null; }); it('requires media-id or channel-token', () => { diff --git a/extensions/amp-app-banner/0.1/test/test-amp-app-banner.js b/extensions/amp-app-banner/0.1/test/test-amp-app-banner.js index e9c54c3a326f..31b3d6b6fb16 100644 --- a/extensions/amp-app-banner/0.1/test/test-amp-app-banner.js +++ b/extensions/amp-app-banner/0.1/test/test-amp-app-banner.js @@ -69,7 +69,7 @@ describes.realWin( } } - function getAppBanner(config = {}) { + async function getAppBanner(config = {}) { if (config.iosMeta) { const meta = doc.createElement('meta'); meta.setAttribute('name', 'apple-itunes-app'); @@ -106,27 +106,24 @@ describes.realWin( banner.id = 'banner0'; doc.body.appendChild(banner); - return banner - .build() - .then(() => banner.layoutCallback()) - .then(() => banner); + await banner.build(); + await banner.layoutCallback(); + return banner; } - function testSetupAndShowBanner() { - return getAppBanner({iosMeta, androidManifest}).then((banner) => { - return banner.implementation_.isDismissed().then(() => { - expect(banner.parentElement).to.not.be.null; - expect(banner).to.not.have.display('none'); - const bannerTop = banner.querySelector( - 'i-amphtml-app-banner-top-padding' - ); - expect(bannerTop).to.exist; - const dismissBtn = banner.querySelector( - '.amp-app-banner-dismiss-button' - ); - expect(dismissBtn).to.exist; - }); - }); + async function testSetupAndShowBanner() { + const banner = await getAppBanner({iosMeta, androidManifest}); + const impl = await banner.getImpl(); + await impl.isDismissed(); + + expect(banner.parentElement).to.not.be.null; + expect(banner).to.not.have.display('none'); + const bannerTop = banner.querySelector( + 'i-amphtml-app-banner-top-padding' + ); + expect(bannerTop).to.exist; + const dismissBtn = banner.querySelector('.amp-app-banner-dismiss-button'); + expect(dismissBtn).to.exist; } function testRemoveBanner(config = {iosMeta, androidManifest}) { @@ -157,19 +154,18 @@ describes.realWin( } function testSuiteIos() { - it('should preconnect to app store', () => { - return getAppBanner({iosMeta}).then((banner) => { - const preconnect = Services.preconnectFor(win); - env.sandbox.stub(preconnect, 'url'); - - const impl = banner.implementation_; - impl.preconnectCallback(true); - expect(preconnect.url).to.be.calledOnce; - expect(preconnect.url).to.have.been.calledWith( - env.sandbox.match.object, // AmpDoc - 'https://itunes.apple.com' - ); - }); + it('should preconnect to app store', async () => { + const banner = await getAppBanner({iosMeta}); + const preconnect = Services.preconnectFor(win); + env.sandbox.stub(preconnect, 'url'); + + const impl = await banner.getImpl(); + impl.preconnectCallback(true); + expect(preconnect.url).to.be.calledOnce; + expect(preconnect.url).to.have.been.calledWith( + env.sandbox.match.object, // AmpDoc + 'https://itunes.apple.com' + ); }); // TODO(alanorozco, #15844): Unskip. @@ -242,48 +238,44 @@ describes.realWin( } function testSuiteAndroid() { - it('should preconnect to play store and preload manifest', () => { - return getAppBanner({androidManifest}).then((banner) => { - const preconnect = Services.preconnectFor(win); - env.sandbox.stub(preconnect, 'url'); - env.sandbox.stub(preconnect, 'preload'); - - const impl = banner.implementation_; - impl.preconnectCallback(true); - expect(preconnect.url).to.have.been.calledOnce; - expect(preconnect.url).to.have.been.calledWith( - env.sandbox.match.object, // AmpDoc - 'https://play.google.com' - ); + it('should preconnect to play store and preload manifest', async () => { + const banner = await getAppBanner({androidManifest}); + const preconnect = Services.preconnectFor(win); + env.sandbox.stub(preconnect, 'url'); + env.sandbox.stub(preconnect, 'preload'); + + const impl = await banner.getImpl(); + impl.preconnectCallback(true); + expect(preconnect.url).to.have.been.calledOnce; + expect(preconnect.url).to.have.been.calledWith( + env.sandbox.match.object, // AmpDoc + 'https://play.google.com' + ); - expect(preconnect.preload).to.be.calledOnce; - expect(preconnect.preload).to.have.been.calledWith( - env.sandbox.match.object, // AmpDoc - 'https://example.com/manifest.json' - ); - }); + expect(preconnect.preload).to.be.calledOnce; + expect(preconnect.preload).to.have.been.calledWith( + env.sandbox.match.object, // AmpDoc + 'https://example.com/manifest.json' + ); }); - it('should preconnect to play store and preload origin-manifest', () => { - return getAppBanner({originManifest: androidManifest}).then( - (banner) => { - const preconnect = Services.preconnectFor(win); - env.sandbox.stub(preconnect, 'url'); - env.sandbox.stub(preconnect, 'preload'); - - const impl = banner.implementation_; - impl.preconnectCallback(true); - expect(preconnect.url).to.have.been.calledOnce; - expect(preconnect.url).to.have.been.calledWith( - env.sandbox.match.object, // AmpDoc - 'https://play.google.com' - ); - expect(preconnect.preload).to.be.calledOnce; - expect(preconnect.preload).to.have.been.calledWith( - env.sandbox.match.object, // AmpDoc - 'https://example.com/manifest.json' - ); - } + it('should preconnect to play store and preload origin-manifest', async () => { + const banner = await getAppBanner({originManifest: androidManifest}); + const preconnect = Services.preconnectFor(win); + env.sandbox.stub(preconnect, 'url'); + env.sandbox.stub(preconnect, 'preload'); + + const impl = await banner.getImpl(); + impl.preconnectCallback(true); + expect(preconnect.url).to.have.been.calledOnce; + expect(preconnect.url).to.have.been.calledWith( + env.sandbox.match.object, // AmpDoc + 'https://play.google.com' + ); + expect(preconnect.preload).to.be.calledOnce; + expect(preconnect.preload).to.have.been.calledWith( + env.sandbox.match.object, // AmpDoc + 'https://example.com/manifest.json' ); }); @@ -363,26 +355,26 @@ describes.realWin( }); describe('Choosing platform', () => { - it('should upgrade to AmpIosAppBanner on iOS', () => { + it('should upgrade to AmpIosAppBanner on iOS', async () => { isIos = true; - return getAppBanner({iosMeta, androidManifest}).then((banner) => { - expect(banner.implementation_).to.be.instanceof(AmpIosAppBanner); - }); + const banner = await getAppBanner({iosMeta, androidManifest}); + const impl = await banner.getImpl(); + expect(impl).to.be.instanceof(AmpIosAppBanner); }); - it('should upgrade to AmpAndroidAppBanner on Android', () => { + it('should upgrade to AmpAndroidAppBanner on Android', async () => { isAndroid = true; - return getAppBanner({iosMeta, androidManifest}).then((banner) => { - expect(banner.implementation_).to.be.instanceof(AmpAndroidAppBanner); - }); + const banner = await getAppBanner({iosMeta, androidManifest}); + const impl = await banner.getImpl(); + expect(impl).to.be.instanceof(AmpAndroidAppBanner); }); - it('should not upgrade if platform not supported', () => { + it('should not upgrade if platform not supported', async () => { isEdge = true; - return getAppBanner({iosMeta, androidManifest}).then((banner) => { - expect(banner.implementation_).to.be.instanceof(AmpAppBanner); - expect(banner.implementation_.upgradeCallback()).to.be.null; - }); + const banner = await getAppBanner({iosMeta, androidManifest}); + const impl = await banner.getImpl(); + expect(impl).to.be.instanceof(AmpAppBanner); + expect(impl.upgradeCallback()).to.be.null; }); }); diff --git a/extensions/amp-audio/0.1/test/test-amp-audio.js b/extensions/amp-audio/0.1/test/test-amp-audio.js index 5b3e172083dd..cd74e044e211 100644 --- a/extensions/amp-audio/0.1/test/test-amp-audio.js +++ b/extensions/amp-audio/0.1/test/test-amp-audio.js @@ -135,22 +135,22 @@ describes.realWin( it( 'should attach `