Skip to content

Commit

Permalink
chore: minimal tests
Browse files Browse the repository at this point in the history
  • Loading branch information
davidnuescheler committed Aug 24, 2022
1 parent 3ce0ace commit ab99563
Show file tree
Hide file tree
Showing 8 changed files with 288 additions and 0 deletions.
14 changes: 14 additions & 0 deletions test/blocks/hero/hero.test.js
Original file line number Diff line number Diff line change
@@ -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;
});
});
59 changes: 59 additions & 0 deletions test/scripts/body.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<header></header>
<main>
<div>
<p>
<picture>
<source media="(max-width: 400px)" srcset="./media_mock.png?width=750&amp;format=webply&amp;optimize=medium">
<img src="/test/scripts/media_mock.png?width=2000&amp;format=webply&amp;optimize=medium" alt="" loading="eager">
</picture>
</p>
<h1 id="this-is-a-heading-1">This is a Heading 1</h1>
<h2 id="this-is-a-heading-2">This is a Heading 2</h2>
<h3 id="this-is-a-heading-3">This is a Heading 3</h3>
<h4 id="this-is-a-heading-4">This is a Heading 4</h4>
<h5 id="this-is-a-heading-5">This is a Heading 5</h5>
<h6 id="this-is-a-heading-6">This is a Heading 6</h6>
<ul>
<li>Red</li>
<li>Green</li>
<li>Blue</li>
</ul>
<ol>
<li>First</li>
<li>Second</li>
<li>Third</li>
</ol>
<p>Lorem ipsum dolor sit amet, <strong>consectetur</strong> 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 <em>consequat</em>. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat <code>nulla</code> pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
culpa qui officia deserunt mollit anim id est <a href="https://www.hlx.live/">laborum</a>.</p>
<p>
<picture>
<source media="(max-width: 400px)"
srcset="/test/scripts/media_mock.png?width=750&amp;format=webply&amp;optimize=medium">
<img src="/test/scripts/media_mock.png?width=2000&amp;format=webply&amp;optimize=medium"
alt="" loading="eager">
</picture>
</p>
<p><a href="https://www.hlx.live/">Button</a></p>
<p><strong><a href="https://www.hlx.live/">Button Bold</a></strong></p>
<p><em><a href="https://www.hlx.live/">Button Italic</a></em></p>
<p><strong><em><a href="https://www.hlx.live/">Button Italic Bold</a></em></strong></p>
<h3 id="testing-a-code-block">Testing a code block</h3>
<pre><code>&lt;meta name="viewport" content="width=device-width, initial-scale=1"/&gt;
&lt;script src="/scripts.js" type="module"&gt;&lt;/script&gt;
&lt;link rel="stylesheet" href="/styles.css"/&gt;
</code></pre>
<div class="example"><
<p>Lorem ipsum dolor sit amet, <strong>consectetur</strong> 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 <em>consequat</em>. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat <code>nulla</code> pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
culpa qui officia deserunt mollit anim id est <a href="https://www.hlx.live/">laborum</a>.</p>
</div>
<div></div><!-- test block without name -->
</div>
<div></div><!-- test removal of empty sections -->
</main>
<footer></footer>
25 changes: 25 additions & 0 deletions test/scripts/config.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<div class="config">
<div>
<div>Prop 0</div>
<div>Plain text</div>
</div>
<div>
<div>Prop 1</div>
<div><p>Paragraph</p></div>
</div>
<div>
<div>Prop 2</div>
<div><p>First paragraph</p><p>Second paragraph</p></div>
</div>
<div>
<div>Prop 3</div>
<div><a href="https://www.adobe.com/">Link</a></div>
</div>
<div>
<div>Prop 4</div>
<div>
<a href="https://www.adobe.com/">First link</a>
<a href="https://www.hlx.live/">Second link</a>
</div>
</div>
</div>
4 changes: 4 additions & 0 deletions test/scripts/dummy.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<!-- dummy html to run scripts.js against in a first pass -->
<header></header>
<main></main>
<footer></footer>
12 changes: 12 additions & 0 deletions test/scripts/head.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<title>Foo</title>
<link rel="canonical" href="https://foo.bar/">
<meta name="description" content="Lorem ipsum dolor sit amet.">
<meta property="og:title" content="Foo">
<meta property="og:description" content="Lorem ipsum dolor sit amet.">
<meta property="og:url" content="https://foo.bar/">
<meta property="og:image" content="https://foo.bar/media_12637fbb67cddc5d293b20975e89028d919270ac0.jpeg?width=1200&amp;format=pjpg&amp;optimize=medium">
<meta property="og:image:secure_url" content="https://foo.bar/media_12637fbb67cddc5d293b20975e89028d919270ac0.jpeg?width=1200&amp;format=pjpg&amp;optimize=medium"">
<meta name="twitter:title" content="Foo">
<meta name="twitter:description" content="Lorem ipsum dolor sit amet.">
<meta name="twitter:image" content="https://foo.bar/media_12637fbb67cddc5d293b20975e89028d919270ac0.jpeg?width=1200&amp;format=pjpg&amp;optimize=medium">
<meta name="viewport" content="width=device-width, initial-scale=1">
Binary file added test/scripts/media_mock.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
171 changes: 171 additions & 0 deletions test/scripts/scripts.test.js
Original file line number Diff line number Diff line change
@@ -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/'],
});
});
});
3 changes: 3 additions & 0 deletions test/scripts/test.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
body {
color: red;
}

0 comments on commit ab99563

Please sign in to comment.