From ab99563903efeea3c596908050cc20143ae6d377 Mon Sep 17 00:00:00 2001 From: David Nuescheler Date: Wed, 24 Aug 2022 14:28:27 -0600 Subject: [PATCH] chore: minimal tests --- test/blocks/hero/hero.test.js | 14 +++ test/scripts/body.html | 59 ++++++++++++ test/scripts/config.html | 25 +++++ test/scripts/dummy.html | 4 + test/scripts/head.html | 12 +++ test/scripts/media_mock.png | Bin 0 -> 1346 bytes test/scripts/scripts.test.js | 171 ++++++++++++++++++++++++++++++++++ test/scripts/test.css | 3 + 8 files changed, 288 insertions(+) create mode 100644 test/blocks/hero/hero.test.js create mode 100644 test/scripts/body.html create mode 100644 test/scripts/config.html create mode 100644 test/scripts/dummy.html create mode 100644 test/scripts/head.html create mode 100644 test/scripts/media_mock.png create mode 100644 test/scripts/scripts.test.js create mode 100644 test/scripts/test.css diff --git a/test/blocks/hero/hero.test.js b/test/blocks/hero/hero.test.js new file mode 100644 index 00000000..7e59287c --- /dev/null +++ b/test/blocks/hero/hero.test.js @@ -0,0 +1,14 @@ +/* eslint-disable no-unused-expressions */ +/* global describe it */ + +import { readFile } from '@web/test-runner-commands'; +import { expect } from '@esm-bundle/chai'; + +document.body.innerHTML = await readFile({ path: '../../scripts/body.html' }); + +describe('Hero block', () => { + it('Builds hero block from picture and h1', async () => { + await import('../../../scripts/scripts.js'); + expect(document.querySelector('.hero')).to.exist; + }); +}); diff --git a/test/scripts/body.html b/test/scripts/body.html new file mode 100644 index 00000000..cdc79c95 --- /dev/null +++ b/test/scripts/body.html @@ -0,0 +1,59 @@ +
+
+
+

+ + + + +

+

This is a Heading 1

+

This is a Heading 2

+

This is a Heading 3

+

This is a Heading 4

+
This is a Heading 5
+
This is a Heading 6
+
    +
  • Red
  • +
  • Green
  • +
  • Blue
  • +
+
    +
  1. First
  2. +
  3. Second
  4. +
  5. Third
  6. +
+

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut + labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut + aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse + cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in + culpa qui officia deserunt mollit anim id est laborum.

+

+ + + + +

+

Button

+

Button Bold

+

Button Italic

+

Button Italic Bold

+

Testing a code block

+
<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<script src="/scripts.js" type="module"></script>
+<link rel="stylesheet" href="/styles.css"/>
+        
+
< +

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut + labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut + aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse + cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in + culpa qui officia deserunt mollit anim id est laborum.

+
+
+
+
+
+ diff --git a/test/scripts/config.html b/test/scripts/config.html new file mode 100644 index 00000000..8a3d5ae6 --- /dev/null +++ b/test/scripts/config.html @@ -0,0 +1,25 @@ +
+
+
Prop 0
+
Plain text
+
+
+
Prop 1
+

Paragraph

+
+
+
Prop 2
+

First paragraph

Second paragraph

+
+
+
Prop 3
+
Link
+
+
+
Prop 4
+
+ First link + Second link +
+
+
diff --git a/test/scripts/dummy.html b/test/scripts/dummy.html new file mode 100644 index 00000000..fbe89155 --- /dev/null +++ b/test/scripts/dummy.html @@ -0,0 +1,4 @@ + +
+
+ diff --git a/test/scripts/head.html b/test/scripts/head.html new file mode 100644 index 00000000..7068482f --- /dev/null +++ b/test/scripts/head.html @@ -0,0 +1,12 @@ +Foo + + + + + + + + + + + diff --git a/test/scripts/media_mock.png b/test/scripts/media_mock.png new file mode 100644 index 0000000000000000000000000000000000000000..4faad891dd0ec0155689ff31761997b5a2b94abc GIT binary patch literal 1346 zcmV-I1-<%-P)ZMEF8w2uHrD^A&3O8Uer!fh}!z)2zBzwXh%F5<13# z(alu1OUmn!%z$~JraJu&0C@^~h`J~IAhdUu-836!26r;m?K9Oi9U?m~#Lic==7k!y z&6Dh=+4qn$xQ)Lh!B_ws{ZCXKIwDWBq@4vveo3QA3ELP$F$3xp9XY`xqiq*l^P>pe z#?P+XK9-_YvgZ3Z*I)4;#v#m19u{9;JY#NoQsaH4W z?TO$DVCa00humPsxk)QAY#J4{Li{%9&p`xlU(gG|HuD||dDR>((_#c~wW)|r4{ZkMcy)zJ@nU+W>?EN(~5aB~O z`tTTfB!Z43muM_ixd7PvtB?NDd5Rn!J0Bz^X%1;hG6+e^hbKx>UJwL95ClOG1VIo4 zK@bE>uzs-V(wG-&D*S$rJK+2~2AAFkrpl`cS@KB)*gIag(#5R|Dz7Gq_;&O~gI{_a zY3`9#za3#)BT_vB=7n01;QX6@c{Pcgq-PgkH_dt}yL-$QM3b31I+aZp)a=#Utscx;MIdRP&5u3e>a!+8p2kfTV9)3IYTtS2D44f&p zp!&q}F_CPt2(X)G>zZq8$*}4$H2A2=aqv(PZEHa;0FLA+qv3Wp&2k(F=jT32wmD`% z-Jp(&{opp{5-M%m90GhZXltXsjPu+xZQC3IT>80UM&Q|+p-KIlFg19jOK3O*xaJZi zaySI|YtYul7I)5b&$MlG2rx9LAbBJ1OAwr)kNDq&F{BVBI5o~xw>IhwI7QaB%@zy7 zP(;`lE4OOIRy=54sQqJj995_OebsHm_7s$#r20h+9cNP8+%a)Jq#F>;A0gkY~Ed>Dn1BoiN7#^%+1poj507*qoM6N<$ Eg2UEYg#Z8m literal 0 HcmV?d00001 diff --git a/test/scripts/scripts.test.js b/test/scripts/scripts.test.js new file mode 100644 index 00000000..88404ba6 --- /dev/null +++ b/test/scripts/scripts.test.js @@ -0,0 +1,171 @@ +/* eslint-disable no-unused-expressions */ +/* global describe before it */ + +import { readFile } from '@web/test-runner-commands'; +import { expect } from '@esm-bundle/chai'; +import sinon from 'sinon'; + +const scripts = {}; + +document.body.innerHTML = await readFile({ path: './dummy.html' }); +document.head.innerHTML = await readFile({ path: './head.html' }); + +describe('Core Helix features', () => { + before(async () => { + const mod = await import('../../scripts/scripts.js'); + Object + .keys(mod) + .forEach((func) => { + scripts[func] = mod[func]; + }); + document.body.innerHTML = await readFile({ path: './body.html' }); + }); + + it('Initializes window.hlx', async () => { + // simulate code base path and turn on lighthouse + document.head.appendChild(document.createElement('script')).src = '/foo/scripts/scripts.js'; + window.history.pushState({}, '', `${window.location.href}&lighthouse=on`); + + scripts.initHlx(); + expect(window.hlx.codeBasePath).to.equal('/foo'); + expect(window.hlx.lighthouse).to.equal(true); + + // test error handling + const url = sinon.stub(window, 'URL'); + scripts.initHlx(); + + // cleanup + url.restore(); + window.hlx.codeBasePath = ''; + window.hlx.lighthouse = false; + Array.from(document.querySelectorAll('script')).pop().remove(); + }); + + it('Sanitizes class name', async () => { + expect(scripts.toClassName('Hello world')).to.equal('hello-world'); + expect(scripts.toClassName(null)).to.equal(''); + }); + + it('Extracts metadata', async () => { + expect(scripts.getMetadata('description')).to.equal('Lorem ipsum dolor sit amet.'); + expect(scripts.getMetadata('og:title')).to.equal('Foo'); + }); + + it('Adds favicon', async () => { + scripts.addFavIcon('/foo.svg'); + const $favIcon = document.querySelector('link[rel="icon"]'); + expect($favIcon.getAttribute('href')).to.equal('/foo.svg'); + }); + + it('Loads CSS', async () => { + // loads a css file and calls callback + const load = await new Promise((resolve) => { + scripts.loadCSS('/test/scripts/test.css', (e) => resolve(e)); + }); + expect(load).to.equal('load'); + expect(getComputedStyle(document.body).color).to.equal('rgb(255, 0, 0)'); + + // does nothing if css already loaded + const noop = await new Promise((resolve) => { + scripts.loadCSS('/test/scripts/test.css', (e) => resolve(e)); + }); + expect(noop).to.equal('noop'); + + // calls callback in case of error + const error = await new Promise((resolve) => { + scripts.loadCSS('/test/scripts/nope.css', (e) => resolve(e)); + }); + expect(error).to.equal('error'); + }); + + it('Collects RUM data', async () => { + const sendBeacon = sinon.stub(navigator, 'sendBeacon'); + // turn on RUM + window.history.pushState({}, '', `${window.location.href}&rum=on`); + delete window.hlx; + + // sends checkpoint beacon + await scripts.sampleRUM('test', { foo: 'bar' }); + expect(sendBeacon.called).to.be.true; + sendBeacon.resetHistory(); + + // sends cwv beacon + await scripts.sampleRUM('cwv', { foo: 'bar' }); + expect(sendBeacon.called).to.be.true; + + // test error handling + sendBeacon.throws(); + await scripts.sampleRUM('error', { foo: 'bar' }); + + sendBeacon.restore(); + }); + + it('Adds publish dependencies', async () => { + // adds single dependency + scripts.addPublishDependencies('/foo'); + expect(window.hlx.dependencies).to.include('/foo'); + + // adds multiple dependencies + scripts.addPublishDependencies(['/bar', '/baz']); + expect(window.hlx.dependencies).to.deep.equal(['/foo', '/bar', '/baz']); + }); + + it('Creates optimized picture', async () => { + const $picture = scripts.createOptimizedPicture('/test/scripts/mock.png'); + expect($picture.querySelector(':scope source[type="image/webp"]')).to.exist; // webp + expect($picture.querySelector(':scope source:not([type="image/webp"])')).to.exist; // fallback + expect($picture.querySelector(':scope img').src).to.include('format=png&optimize=medium'); // default + }); + + it('Normalizes headings', async () => { + const numHeadings = document.querySelectorAll('h1, h2, h3, h4, h5, h6').length; + scripts.normalizeHeadings(document.querySelector('main'), ['h1', 'h2', 'h3']); + expect(document.querySelectorAll('h1, h2, h3, h4, h5, h6').length).to.equal(numHeadings); + expect(document.querySelectorAll('h4, h5, h6').length).to.equal(0); + }); +}); + +describe('Sections and blocks', () => { + it('Decorates sections', async () => { + scripts.decorateSections(document.querySelector('main')); + expect(document.querySelectorAll('main .section').length).to.equal(2); + }); + + it('Decorates blocks', async () => { + scripts.decorateBlocks(document.querySelector('main')); + expect(document.querySelectorAll('main .block').length).to.equal(1); + }); + + it('Loads blocks', async () => { + await scripts.loadBlocks(document.querySelector('main')); + document.querySelectorAll('main .block').forEach(($block) => { + expect($block.dataset.blockStatus).to.equal('loaded'); + }); + }); + + it('Updates section status', async () => { + scripts.updateSectionsStatus(document.querySelector('main')); + document.querySelectorAll('main .section').forEach(($section) => { + expect($section.dataset.sectionStatus).to.equal('loaded'); + }); + + // test section with block still loading + const $section = document.querySelector('main .section'); + delete $section.dataset.sectionStatus; + $section.querySelector(':scope .block').dataset.blockStatus = 'loading'; + scripts.updateSectionsStatus(document.querySelector('main')); + expect($section.dataset.sectionStatus).to.equal('loading'); + }); + + it('Reads block config', async () => { + document.querySelector('main .section > div').innerHTML += await readFile({ path: './config.html' }); + const cfg = scripts.readBlockConfig(document.querySelector('main .config')); + expect(cfg).to.deep.include({ + 'prop-0': 'Plain text', + 'prop-1': 'Paragraph', + 'prop-2': ['First paragraph', 'Second paragraph'], + 'prop-3': 'https://www.adobe.com/', + 'prop-4': ['https://www.adobe.com/', 'https://www.hlx.live/'], + }); + }); +}); diff --git a/test/scripts/test.css b/test/scripts/test.css new file mode 100644 index 00000000..b05faf8e --- /dev/null +++ b/test/scripts/test.css @@ -0,0 +1,3 @@ +body { + color: red; +}