diff --git a/bedrock/base/templates/base-pebbles.html b/bedrock/base/templates/base-pebbles.html index df84bf1fc3..2f6375280f 100644 --- a/bedrock/base/templates/base-pebbles.html +++ b/bedrock/base/templates/base-pebbles.html @@ -90,6 +90,8 @@ data-global-fx-out-of-date-banner-confirm="{{ _('Update Firefox') }}" {% block string_data %}{% endblock %}> + {% block page_banner %}{% endblock %} + {% block site_header %} {% include 'includes/protocol/navigation/menu-mozilla/index.html' %} {% endblock %} diff --git a/bedrock/base/templates/includes/banners/base.html b/bedrock/base/templates/includes/banners/base.html new file mode 100644 index 0000000000..b2c222b168 --- /dev/null +++ b/bedrock/base/templates/includes/banners/base.html @@ -0,0 +1,15 @@ +{# This Source Code Form is subject to the terms of the Mozilla Public + # License, v. 2.0. If a copy of the MPL was not distributed with this + # file, You can obtain one at http://mozilla.org/MPL/2.0/. -#} + + diff --git a/bedrock/base/templates/includes/banners/fundraiser.html b/bedrock/base/templates/includes/banners/fundraiser.html new file mode 100644 index 0000000000..5e177f1c53 --- /dev/null +++ b/bedrock/base/templates/includes/banners/fundraiser.html @@ -0,0 +1,55 @@ +{# This Source Code Form is subject to the terms of the Mozilla Public + # License, v. 2.0. If a copy of the MPL was not distributed with this + # file, You can obtain one at http://mozilla.org/MPL/2.0/. -#} + +{% extends 'includes/banners/base.html' %} + +{% block banner_title %} + {{ _('We all love the web. Join Mozilla in defending it.') }} +{% endblock %} + +{% block banner_content %} +
+ {% trans %} + Big corporations try to restrict how we access the web. Misinformation + makes it harder for us to find the truth. Web-connected devices go to + market without basic security standards. The non-profit Mozilla Foundation + fights for a healthier internet. Will you donate today? + {% endtrans %} +
+ + +{% endblock %} diff --git a/bedrock/mozorg/templates/mozorg/home/home-en.html b/bedrock/mozorg/templates/mozorg/home/home-en.html index e840db4976..b58b625fdc 100644 --- a/bedrock/mozorg/templates/mozorg/home/home-en.html +++ b/bedrock/mozorg/templates/mozorg/home/home-en.html @@ -39,13 +39,16 @@ {% block page_css %} {{ css_bundle('home-2018') }} + + {% if switch('fundraising-banner') %} + {{ css_bundle('fundraising-banner') }} + {% endif %} {% endblock %} -{% block site_header %} - {% if switch('home-fundraising-sept2019') %} - {% include 'mozorg/home/includes/fundraiser.html' %} +{% block page_banner %} + {% if switch('fundraising-banner') %} + {% include 'includes/banners/fundraiser.html' %} {% endif %} - {% include 'includes/protocol/navigation/menu-mozilla/index.html' %} {% endblock %} {% block content %} @@ -206,8 +209,9 @@ {% block js %} {{ js_bundle('home') }} - {% if switch('home-fundraising-sept2019') %} - {{ js_bundle('home-fundraiser') }} + + {% if switch('fundraising-banner') %} + {{ js_bundle('fundraising-banner') }} {% endif %} {% endblock %} diff --git a/bedrock/mozorg/templates/mozorg/home/home.html b/bedrock/mozorg/templates/mozorg/home/home.html index 245a06e275..10a7de3e54 100644 --- a/bedrock/mozorg/templates/mozorg/home/home.html +++ b/bedrock/mozorg/templates/mozorg/home/home.html @@ -33,7 +33,17 @@ accessible to all.') }} {% endblock %} {% block page_css %} -{{ css_bundle('home') }} + {{ css_bundle('home') }} + + {% if switch('fundraising-banner') %} + {{ css_bundle('fundraising-banner') }} + {% endif %} +{% endblock %} + +{% block page_banner %} + {% if switch('fundraising-banner') %} + {% include 'includes/banners/fundraiser.html' %} + {% endif %} {% endblock %} {% block content %} @@ -196,7 +206,11 @@ accessible to all.') }} {% endblock %} {% block js %} -{{ js_bundle('newsletter') }} + {{ js_bundle('newsletter') }} + + {% if switch('fundraising-banner') %} + {{ js_bundle('fundraising-banner') }} + {% endif %} {% endblock %} {% block structured_data %} diff --git a/bedrock/mozorg/templates/mozorg/home/includes/fundraiser.html b/bedrock/mozorg/templates/mozorg/home/includes/fundraiser.html deleted file mode 100644 index 2a5284c122..0000000000 --- a/bedrock/mozorg/templates/mozorg/home/includes/fundraiser.html +++ /dev/null @@ -1,58 +0,0 @@ -{# This Source Code Form is subject to the terms of the Mozilla Public - # License, v. 2.0. If a copy of the MPL was not distributed with this - # file, You can obtain one at http://mozilla.org/MPL/2.0/. -#} - - diff --git a/docs/banners.rst b/docs/banners.rst new file mode 100644 index 0000000000..0f94d5076c --- /dev/null +++ b/docs/banners.rst @@ -0,0 +1,111 @@ +.. This Source Code Form is subject to the terms of the Mozilla Public +.. License, v. 2.0. If a copy of the MPL was not distributed with this +.. file, You can obtain one at http://mozilla.org/MPL/2.0/. + +.. _banners: + +======= +Banners +======= + +Creating page banners +--------------------- + +Any page on bedrock can incorporate a top of page banner as a temporary +feature. An example of such a banner is the MOFO fundraising form that gets +shown on the home page several times a year. + +Banners can be inserted into any page template by using the ``page_banner`` +block. Banners can also be toggled on and off using a switch: + +.. code-block:: jinja + + {% block page_banner %} + {% if switch('fundraising-banner') %} + {% include 'includes/banners/fundraiser.html' %} + {% endif %} + {% endblock %} + +Banner templates should extend the *base banner template*, and content can +then be inserted using ``banner_title`` and ``banner_content`` blocks: + +.. code-block:: jinja + + {% extends 'includes/banners/base.html' %} + + {% block banner_title %}We all love the web. Join Mozilla in defending it.{% endblock %} + + {% block banner_content %} + + {% endblock %} + +CSS styles for banners should be located in ``media/css/base/banners/``, and +should extend common base banner styles: + +.. code-block:: css + + @import 'includes/base'; + +To initiate a banner on a page, include ``media/js/base/mozilla-banner.js`` in +your page bundle and then initiate the banner using a unique ID. The ID will +be used as a cookie identifier should someone dismiss a banner and not wish to +see it again. + +.. code-block:: javascript + + (function() { + 'use strict'; + + function onLoad() { + window.Mozilla.Banner.init('fundraiser-sept2019'); + } + + window.Mozilla.run(onLoad); + + })(); + +L10n for page banners +~~~~~~~~~~~~~~~~~~~~~ + +Becuase banners can technically be shown on any page, they need to be broadly +translated, or alternatively limited to the subset of locales that have +translations. Each banner should have its own ``.lang`` or ``.ftl`` associated +with it, and accessible to the template or view it gets used in. + +Fundraising banner +------------------ + +The fundraising banner typically gets shown on the home page, but +technically can be shown on any page in bedrock. The donation +parameters that get passed to the form require some extra context +data that needs to get passed to the template via the view in order +to work. For example: + +.. code-block:: python + + def home_view(request): + locale = l10n_utils.get_locale(request) + donate_params = settings.DONATE_PARAMS.get( + locale, settings.DONATE_PARAMS['en-US']) + + # presets are stored as a string but, for the home banner + # we need it as a list. + donate_params['preset_list'] = donate_params['presets'].split(',') + + ctx = { + 'donate_params': donate_params + } + + return l10n_utils.render(request, 'mozorg/home/home.html', ctx) + +The HTML and CSS assets for the fundraising banner are located in: + +- ``bedrock/base/templates/includes/banners/fundraiser.html`` +- ``media/css/base/banners/fundraiser.scss`` + +.. note:: + + Strings for the fundraising banner are currently in a bit of a mess. + Some are in ``main.lang``, whilst others are in the homepage ``.lang`` + file. This means it can't be shown outside of the home page currently, + unless in English only. This needs fixing when we migrate over to Fluent. diff --git a/docs/index.rst b/docs/index.rst index ee856d682d..3db36fab3b 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -33,6 +33,7 @@ Contents javascript-libs newsletters content-cards + banners uitour send-to-device firefox-accounts diff --git a/docs/l10n.rst b/docs/l10n.rst index 5216d6cbad..3765a6fdfd 100644 --- a/docs/l10n.rst +++ b/docs/l10n.rst @@ -121,7 +121,7 @@ Our convention for string ID creation is the following: 3. IDs should be prefixed with the name of the template file (e.g. ``firefox-new-skyline`` for ``firefox-new-skyline.html``) 4. If you need to create a new string for the same place on a page and to transition to it as it is translated, you can add a version suffix to the string ID: e.g. ``firefox-new-skyline-main-page-title-v2``. -4. The ID should be as descriptive as possible to make sense to the developer, but could be anything as long as it adheres +5. The ID should be as descriptive as possible to make sense to the developer, but could be anything as long as it adheres to the rules above. The ``ftl`` helper function diff --git a/media/css/mozorg/home/fundraiser.scss b/media/css/base/banners/fundraiser.scss similarity index 57% rename from media/css/mozorg/home/fundraiser.scss rename to media/css/base/banners/fundraiser.scss index a60ac1cfab..3a41fdabb4 100644 --- a/media/css/mozorg/home/fundraiser.scss +++ b/media/css/base/banners/fundraiser.scss @@ -6,6 +6,7 @@ $font-path: '/media/fonts'; $image-path: '/media/protocol/img'; @import '../../../protocol/css/includes/lib'; +@import 'includes/base'; @keyframes swoosh { 0% {background: $color-blue-40;} @@ -35,57 +36,14 @@ $image-path: '/media/protocol/img'; 100% {background-color: $color-green-40;} } -.c-fundraiser { - @include clearfix; - background-size: cover; - background-color: black; - color: $color-white; - padding: $spacing-md 0 0; - position: relative; - z-index: 3; - - // hide by default if JS is available to avoid flicker - // (if visitor previously dismissed) - .js & { - display: none; - } - - .mzp-c-button.mzp-t-secondary { - background-color: transparent; - - &:focus, - &:hover { - background-color: rgba(255, 255, 255, .15); - } - } -} - -.content { - vertical-align: middle; -} - -.c-fundraiser-title { - @include font-mozilla; - @include text-display-lg; - font-weight: bold; +.c-banner-title { line-height: 1.25em; + span { animation-duration: 3s; animation-name: swoosh; background-color: $color-green-40; - color: black; - } -} - -.c-fundraiser-amount-input { - left: 0; - opacity: 0; - position: absolute; - top: 0; - - &:checked + .mzp-c-button.mzp-t-secondary { - background-color: rgba(255, 255, 255, .25); - font-weight: bold; + color: $color-black; } } @@ -96,85 +54,56 @@ $image-path: '/media/protocol/img'; display: inline-block; &:first-child { - @include bidi(((margin-right, $spacing-lg, 0),(margin-left, 0, $spacing-lg))); + @include bidi(( + (margin-right, $spacing-lg, 0), + (margin-left, 0, $spacing-lg) + )); } } } .c-fundraiser-options { + margin-bottom: $spacing-sm; + + .mzp-c-button.mzp-t-secondary { + background-color: transparent; + + &:focus, + &:hover { + background-color: rgba(255, 255, 255, .15); + } + } + label { @include bidi(((margin, $spacing-sm $spacing-sm 0 0, 0 0 $spacing-sm $spacing-sm),)); display: inline-block; position: relative; &:first-child { - @include bidi(((margin-left, 0, $spacing-sm),(margin-right, $spacing-sm, 0))); + @include bidi(( + (margin-left, 0, $spacing-sm), + (margin-right, $spacing-sm, 0) + )); + } + } + + .c-fundraiser-amount-input { + left: 0; + opacity: 0; + position: absolute; + top: 0; + + &:checked + .mzp-c-button.mzp-t-secondary { + background-color: rgba(255, 255, 255, .25); + font-weight: bold; } } @media #{$mq-md} { - @include bidi(((margin-right, $spacing-md, 0),(margin-left, 0, $spacing-md))); + @include bidi(( + (margin-right, $spacing-md, 0), + (margin-left, 0, $spacing-md) + )); display: inline-block; } - margin-bottom: $spacing-sm; -} - -// Close button -.c-fundraiser-close { - @include background-size(20px 20px); - @include bidi(((right, $spacing-sm, auto), (left, auto, $spacing-sm))); - @include image-replaced; - background: transparent url('#{$image-path}/icons/close-white.svg') center center no-repeat; - border: none; - display: none; - height: 42px; - min-width: 0; - padding: 0; - position: absolute; - top: $spacing-sm; - width: 42px; - z-index: 1; - - &:hover, - &:focus { - @include transition(transform .1s ease-in-out); - @include transform(scale(1.1)); - } - - &:focus { - outline: 1px dotted $color-white; - } - - // hide the 'Close' text - span { - @include visually-hidden; - } - - // only display when JS is available - .js & { - display: block; - } -} - -@media #{$mq-lg} { - .c-fundraiser { - padding-bottom: $spacing-md; - } - - .content { - display: table; - } - - .c-fundraiser-title { - @include bidi(((table-cell, left, right),(padding-right, $spacing-xl, 0), (padding-left, 0, $spacing-xl))); - @include grid-half; - display: table-cell; - vertical-align: middle; - } - - .c-fundraiser-content { - @include bidi(((table-cell, right, left),)); - @include grid-half; - display: table-cell; - } } diff --git a/media/css/base/banners/includes/_base.scss b/media/css/base/banners/includes/_base.scss new file mode 100644 index 0000000000..b09f88294a --- /dev/null +++ b/media/css/base/banners/includes/_base.scss @@ -0,0 +1,99 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +$font-path: '/media/fonts'; +$image-path: '/media/protocol/img'; + +@import '../../../../protocol/css/includes/lib'; + +.c-banner { + @include clearfix; + @include background-size(cover); + background-color: $color-black; + color: $color-white; + padding: $spacing-md 0 0; + position: relative; + z-index: 3; + + a:link, + a:visited { + color: $color-white; + } + + // hide by default if JS is available to avoid flicker + // (if visitor previously dismissed) + .js & { + display: none; + } + + // conditional class used to display the banner. + &.c-banner-is-visible { + display: block; + } + + @media #{$mq-lg} { + padding-bottom: $spacing-md; + } +} + +.c-banner-title { + @include font-mozilla; + @include text-display-lg; + + @media #{$mq-lg} { + @include bidi(( + (table-cell, left, right), + (padding-right, $spacing-xl, 0), + (padding-left, 0, $spacing-xl) + )); + @include grid-half; + display: table-cell; + vertical-align: middle; + } +} + +.c-banner-content { + @media #{$mq-lg} { + @include bidi(((table-cell, right, left),)); + @include grid-half; + display: table-cell; + } +} + +// Close button +.c-banner-close { + @include background-size(20px 20px); + @include bidi(((right, $spacing-sm, auto), (left, auto, $spacing-sm))); + @include image-replaced; + background: transparent url('#{$image-path}/icons/close-white.svg') center center no-repeat; + border: none; + display: none; + height: 42px; + min-width: 0; + padding: 0; + position: absolute; + top: $spacing-sm; + width: 42px; + z-index: 1; + + &:hover, + &:focus { + @include transition(transform .1s ease-in-out); + @include transform(scale(1.1)); + } + + &:focus { + outline: 1px dotted $color-white; + } + + // hide the 'Close' text + span { + @include visually-hidden; + } + + // only display when JS is available + .js & { + display: block; + } +} diff --git a/media/js/base/mozilla-banner.js b/media/js/base/mozilla-banner.js new file mode 100644 index 0000000000..041376a70d --- /dev/null +++ b/media/js/base/mozilla-banner.js @@ -0,0 +1,75 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +// Create namespace +if (typeof window.Mozilla === 'undefined') { + window.Mozilla = {}; +} + +(function() { + 'use strict'; + + var _fundraiser; + + var Banner = {}; + + Banner.setCookie = function(id) { + var date = new Date(); + var cookieDuration = 1 * 24 * 60 * 60 * 1000; // 1 day expiration + date.setTime(date.getTime() + cookieDuration); // 1 day expiration + Mozilla.Cookies.setItem(id, true, date.toUTCString(), '/'); + }; + + Banner.hasCookie = function(id) { + return Mozilla.Cookies.hasItem(id); + }; + + Banner.close = function() { + // Remove the banner from the DOM. + _fundraiser.parentNode.removeChild(_fundraiser); + + // Set a cookie to not display it again. + Banner.setCookie(Banner.id); + + // Track the event in GA. + window.dataLayer.push({ + 'event': 'in-page-interaction', + 'eLabel': 'Banner Dismissal', + 'data-banner-name': Banner.id, + 'data-banner-dismissal': '1' + }); + }; + + Banner.show = function() { + // display the banner + _fundraiser.classList.add('c-banner-is-visible'); + + // wire up close button + document.getElementById('page-banner-close').addEventListener('click', Banner.close, false); + }; + + Banner.init = function(id) { + var cookiesEnabled = typeof Mozilla.Cookies !== 'undefined' && Mozilla.Cookies.enabled(); + + _fundraiser = document.getElementById('page-banner'); + + /** + * If the banner does not exist on a page, + * or there's not a valid banner ID then do nothing. + */ + if (!_fundraiser || typeof id !== 'string') { + return false; + } + + Banner.id = id; + + // Show only if cookies enabled & banner not previously dismissed. + if (cookiesEnabled && !Banner.hasCookie(Banner.id)) { + Banner.show(); + } + }; + + window.Mozilla.Banner = Banner; + +})(); diff --git a/media/js/mozorg/home/banner-init.js b/media/js/mozorg/home/banner-init.js new file mode 100644 index 0000000000..71c00775c4 --- /dev/null +++ b/media/js/mozorg/home/banner-init.js @@ -0,0 +1,14 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +(function() { + 'use strict'; + + function onLoad() { + window.Mozilla.Banner.init('fundraising-banner'); + } + + window.Mozilla.run(onLoad); + +})(); diff --git a/media/js/mozorg/home/fundraiser.js b/media/js/mozorg/home/fundraiser.js deleted file mode 100644 index 32a40ed9dd..0000000000 --- a/media/js/mozorg/home/fundraiser.js +++ /dev/null @@ -1,38 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -(function(Mozilla) { - 'use strict'; - - var fundraiser = document.getElementById('fundraiser'); - var fundraiserClose = document.getElementById('fundraiser-close'); - var cookieDurationDays = 1; - var cookiesOK = typeof Mozilla.Cookies !== 'undefined' && Mozilla.Cookies.enabled(); - var storageKey = 'fundraiser-sept2019'; - var wasClosed = false; - - // see if visitor previously dismissed the banner - if (cookiesOK) { - wasClosed = Mozilla.Cookies.getItem(storageKey); - } - - if (!wasClosed) { - // show the banner - fundraiser.style.display = 'block'; - - // wire up close button - fundraiserClose.addEventListener('click', function() { - var d; - - fundraiser.parentNode.removeChild(fundraiser); - - if (cookiesOK) { - d = new Date(); - d.setTime(d.getTime() + (cookieDurationDays * 24 * 60 * 60 * 1000)); // 1 day expiration - Mozilla.Cookies.setItem(storageKey, true, d.toUTCString(), '/'); - } - }, false); - } - -})(window.Mozilla); \ No newline at end of file diff --git a/media/static-bundles.json b/media/static-bundles.json index 08f77e13a5..bd23d015f1 100644 --- a/media/static-bundles.json +++ b/media/static-bundles.json @@ -248,11 +248,16 @@ }, { "files": [ - "css/mozorg/home/home-2018.scss", - "css/mozorg/home/fundraiser.scss" + "css/mozorg/home/home-2018.scss" ], "name": "home-2018" }, + { + "files": [ + "css/base/banners/fundraiser.scss" + ], + "name": "fundraising-banner" + }, { "files": [ "css/pebbles/base/oldIE.scss" @@ -1055,9 +1060,10 @@ }, { "files": [ - "js/mozorg/home/fundraiser.js" + "js/base/mozilla-banner.js", + "js/mozorg/home/banner-init.js" ], - "name": "home-fundraiser" + "name": "fundraising-banner" }, { "files": [ diff --git a/tests/unit/karma.conf.js b/tests/unit/karma.conf.js index 91276df882..8b6facab92 100644 --- a/tests/unit/karma.conf.js +++ b/tests/unit/karma.conf.js @@ -18,6 +18,7 @@ module.exports = function(config) { 'media/js/base/mozilla-client.js', 'media/js/base/search-params.js', // end common dependencies. + 'media/js/base/mozilla-banner.js', 'media/js/base/mozilla-run.js', 'media/js/base/core-datalayer-page-id.js', 'media/js/base/core-datalayer.js', @@ -38,6 +39,7 @@ module.exports = function(config) { 'media/js/firefox/all/all-downloads-unified.js', 'media/js/firefox/new/yandex/scene1.js', 'media/js/ie/mozilla-utils-ie.js', + 'tests/unit/spec/base/mozilla-banner.js', 'tests/unit/spec/base/mozilla-run.js', 'tests/unit/spec/base/core-datalayer-page-id.js', 'tests/unit/spec/base/core-datalayer.js', diff --git a/tests/unit/spec/base/mozilla-banner.js b/tests/unit/spec/base/mozilla-banner.js new file mode 100644 index 0000000000..49fd8349b3 --- /dev/null +++ b/tests/unit/spec/base/mozilla-banner.js @@ -0,0 +1,84 @@ +/* For reference read the Jasmine and Sinon docs + * Jasmine docs: http://pivotal.github.io/jasmine/ + * Sinon docs: http://sinonjs.org/docs/ + */ + +/* global sinon, */ + +describe('mozilla-banner.js', function() { + 'use strict'; + + beforeEach(function() { + // stub out Mozilla.Cookie lib + window.Mozilla.Cookies = sinon.stub(); + window.Mozilla.Cookies.enabled = sinon.stub().returns(true); + window.Mozilla.Cookies.setItem = sinon.stub(); + window.Mozilla.Cookies.getItem = sinon.stub(); + window.Mozilla.Cookies.hasItem = sinon.stub(); + + // stub out google tag manager + window.dataLayer = sinon.stub(); + window.dataLayer.push = sinon.stub(); + }); + + describe('init', function() { + + var bannerId = 'test-banner'; + + beforeEach(function() { + var banner = ''; + document.body.insertAdjacentHTML('beforeend', banner); + }); + + afterEach(function() { + var banner = document.getElementById('page-banner'); + banner.parentNode.removeChild(banner); + + Mozilla.Banner.id = null; + }); + + it('should show the banner if no cookie is set', function() { + spyOn(window.Mozilla.Banner, 'hasCookie').and.returnValue(false); + spyOn(window.Mozilla.Banner, 'show'); + Mozilla.Banner.init(bannerId); + expect(Mozilla.Banner.id).toEqual(bannerId); + expect(Mozilla.Banner.show).toHaveBeenCalled(); + }); + + it('should not show the banner if there is a cookie', function() { + spyOn(window.Mozilla.Banner, 'hasCookie').and.returnValue(true); + spyOn(window.Mozilla.Banner, 'show'); + Mozilla.Banner.init(bannerId); + expect(Mozilla.Banner.id).toEqual(bannerId); + expect(Mozilla.Banner.show).not.toHaveBeenCalled(); + }); + }); + + describe('close', function() { + var bannerId = 'test-banner'; + + beforeEach(function() { + var banner = ''; + document.body.insertAdjacentHTML('beforeend', banner); + }); + + afterEach(function() { + Mozilla.Banner.id = null; + }); + + it('should close the banner when clicked and set a cookie', function() { + spyOn(window.Mozilla.Banner, 'hasCookie').and.returnValue(false); + spyOn(window.Mozilla.Banner, 'setCookie'); + spyOn(window.Mozilla.Banner, 'close').and.callThrough(); + Mozilla.Banner.init(bannerId); + var banner = document.getElementById('page-banner'); + expect(banner.classList.contains('c-banner-is-visible')).toBeTruthy(); + var close = document.getElementById('page-banner-close'); + close.click(); + expect(Mozilla.Banner.close).toHaveBeenCalled(); + expect(Mozilla.Banner.setCookie).toHaveBeenCalledWith(bannerId); + expect(document.getElementById('page-banner')).toBeNull(); + }); + }); + +});