From 064a8be1840422e75f2fd4ad6c5d7aaa0665a458 Mon Sep 17 00:00:00 2001 From: markpadbe Date: Tue, 10 Sep 2024 11:52:43 -0700 Subject: [PATCH 1/3] Move files out of mep folder --- libs/blocks/timeline/timeline.css | 142 +++++++++++++++++++++++++++ libs/blocks/timeline/timeline.js | 153 ++++++++++++++++++++++++++++++ libs/utils/utils.js | 1 + 3 files changed, 296 insertions(+) create mode 100644 libs/blocks/timeline/timeline.css create mode 100644 libs/blocks/timeline/timeline.js diff --git a/libs/blocks/timeline/timeline.css b/libs/blocks/timeline/timeline.css new file mode 100644 index 0000000000..18f1de7c6d --- /dev/null +++ b/libs/blocks/timeline/timeline.css @@ -0,0 +1,142 @@ +.timeline { + box-sizing: border-box; + padding: 0 0 var(--spacing-xl) 0; + width: var(--grid-container-width); + max-width: 968px; + margin: 0 auto; +} + +.timeline .row { + display: grid; +} + +.timeline h1, +.timeline h2, +.timeline h3, +.timeline h4, +.timeline h5, +.timeline h6, +.timeline p { + color: var(--text-color); + margin: 0; + font-size: var(--type-body-xs-size); + line-height: var(--type-body-xs-lh); +} + +.timeline .row:nth-child(2)>div { + display: flex; + flex-direction: row; + align-items: center; +} + +.timeline .row:nth-of-type(1)>.right>div+div { + text-align: right; + display: flex; + flex-direction: column; + align-items: flex-end; +} + +.timeline .row:nth-of-type(1)>.left>div>* { + max-width: 100px; + padding-right: var(--spacing-m); +} + +.dark .timeline .row:nth-child(3)>div *, +.timeline.dark .row:nth-child(3)>div * { + color: var(--color-black); +} + +.timeline .row:nth-of-type(1)>.right>div+div>* { + max-width: 100px; +} + +.timeline .row:nth-of-type(1)>.right, +.timeline .row:nth-of-type(2)>.right { + display: grid; + justify-content: space-between; +} + +.timeline .row:nth-of-type(1)>.right { + grid-template-columns: minmax(110px, 1fr) 1fr; +} + +.timeline .row:nth-of-type(2)>.right { + grid-template-columns: 2px 2px; +} + +.timeline .row:nth-of-type(1)>.right>div:nth-of-type(1) { + max-width: 135px; + padding-right: var(--spacing-xxs); +} + +.timeline .bar { + height: 20px; + width: 2px; + border-radius: 1px; + margin: var(--spacing-xxs) 0; +} + +.timeline .row:nth-of-type(3) p { + text-align: center; + font-weight: 700; + padding: 4px var(--spacing-xxs); + height: 100%; + display: flex; + flex-direction: column; + justify-content: center; + border-radius: 4px; +} + +.timeline .row:nth-of-type(3) .left p { + margin-right: 1px; +} + +.timeline .row:nth-of-type(3) .right p { + margin-left: 3px; +} + +.dark .timeline .row:nth-child(1)>div>div>*, +.timeline.dark .row:nth-child(1)>div>div>* { + color: var(--color-white); +} + +[dir="rtl"] .timeline .row:nth-of-type(1)>.left>div>* { + padding: 0 0 0 var(--spacing-m); + text-align: right; +} + +[dir="rtl"] .timeline .row:nth-of-type(1)>.right>div+div { + padding: 0 0 var(--spacing-xxs) 0; + text-align: left; +} + +[dir="rtl"] .timeline .row:nth-of-type(3) .left p { + margin: 0 0 0 1px; +} + +[dir="rtl"] .timeline .row:nth-of-type(3) .right p { + margin: 0 3px 0 0; +} + +[dir="rtl"] .timeline .row:nth-of-type(1)>.right>div:nth-of-type(1) { + padding: 0 0 0 var(--spacing-xxs); +} + +@media screen and (min-width: 600px) { + .timeline { + width: 100%; + padding: 0 var(--grid-margins-width) var(--spacing-xl) var(--grid-margins-width); + } + + .dialog-modal .timeline { + padding: 0 var(--spacing-xl) var(--spacing-xl) var(--spacing-xl); + } +} + +@media screen and (min-width: 1200px) { + .timeline { + padding: 0 0 var(--spacing-xxl) 0; + width: 968px; + max-width: 100%; + } +} diff --git a/libs/blocks/timeline/timeline.js b/libs/blocks/timeline/timeline.js new file mode 100644 index 0000000000..ba2ea4aacf --- /dev/null +++ b/libs/blocks/timeline/timeline.js @@ -0,0 +1,153 @@ +import { createTag } from '../../utils/utils.js'; + +function isColor(str) { + const hexRegex = /^#(?:[0-9a-fA-F]{3}){1,2}$/; + const rgbRegex = /^rgb\(\s*\d{1,3}\s*,\s*\d{1,3}\s*,\s*\d{1,3}\s*\)$/; + return hexRegex.test(str) || rgbRegex.test(str); +} + +function isGradient(str) { + return str.startsWith('linear-gradient'); +} + +function isColorOrGradient(str) { + return isColor(str) || isGradient(str); +} + +function getColWidth(text, colWidths) { + const numRegex = /\b\d{1,3}\b/; + colWidths.push((text.match(numRegex) || [])[0]); +} +function createRow() { + return [createTag('div', { class: 'row' }), + createTag('div', { class: 'left' }), + createTag('div', { class: 'right' }), + ]; +} +function createBars(index) { + return index === 0 + ? [createTag('div', { class: 'bar' })] : [createTag('div', { class: 'bar' }), createTag('div', { class: 'bar' })]; +} +function addBarRow() { + const [barRow, left, right] = createRow(); + const sides = [left, right]; + sides.forEach((text, index) => { + sides[index].append(...createBars(index)); + barRow.append(sides[index]); + }); + return barRow; +} +function addBottomRow(periodText) { + const [periodRow, left, right] = createRow(); + const sides = [left, right]; + periodText.forEach((text, index) => { + sides[index].append(createTag('p', { class: 'period body-s' }, text)); + periodRow.append(sides[index]); + }); + return periodRow; +} + +function setBG(el, color) { + el.style.background = color; +} + +function updateForRTL(lgStr, el) { + if (el.closest('[dir="rtl"]')) { + return lgStr.replace(/to right|to left|90deg|180deg|turn 0.25|turn 0.75/g, (match) => { + const converter = { + 'turn 0.25': 'turn 0.75', + 'turn 0.75': 'turn 0.25', + '90deg': '180deg', + '180deg': '90deg', + 'to right': 'to left', + 'to left': 'to right', + }; + + return converter[match]; + }); + } + return lgStr; +} +function setColors(colors, fragment, el) { + const barEls = fragment.querySelectorAll('.bar'); + const periodEls = fragment.querySelectorAll('.period'); + if (colors?.length === 2 && isColorOrGradient(colors[0]) && isColorOrGradient(colors[1])) { + if (barEls.length === 3 || periodEls.length === 2) { + const leftColor = colors[0]; + const rightColor = colors[1]; + let firstBar; let secondBar; let thirdBar; + if (isGradient(leftColor)) { + leftColor.split(' ').forEach((color) => { + if (isColor(color) && !firstBar) { + firstBar = color; + setBG(barEls[0], firstBar); + } else if (isColor(color)) { + secondBar = color; + setBG(barEls[1], secondBar); + } + }); + } else { + setBG(barEls[0], leftColor); + setBG(barEls[1], leftColor); + } + if (isGradient(rightColor)) { + leftColor.split(' ').forEach((color) => { + if (isColor(color) && !thirdBar) { + thirdBar = color; + setBG(barEls[2], thirdBar); + } + }); + } else { + setBG(barEls[2], rightColor); + } + setBG(periodEls[0], updateForRTL(leftColor, el)); + setBG(periodEls[1], updateForRTL(rightColor, el)); + } + } +} + +function colWidthsNotValid(colWidths) { + return (colWidths.length !== 2 || colWidths.some((value) => Number.isNaN(value))); +} +function updateColWidths(colWidths, fragment) { + if (colWidthsNotValid(colWidths)) return; + const total = Number(colWidths[0]) + Number(colWidths[1]); + const right = Math.floor((Number(colWidths[1]) / total) * 10000) / 100; + const colString = `1fr minmax(${String(right)}%, 150px)`; + fragment.querySelectorAll('.row').forEach((row) => { + row.style.gridTemplateColumns = colString; + }); +} +export default function init(el) { + const fragment = document.createDocumentFragment(); + const [textRow, left, right] = createRow(); + const rows = el.querySelectorAll(':scope > div > div'); + const colors = []; const periodText = []; const colWidths = []; + rows.forEach((row, index) => { + const side = index === 0 ? left : right; + const color = row.firstElementChild?.textContent?.trim(); + const p = row.querySelector(':scope > p:last-child'); + if (p) { + const [text, period] = p.textContent.trim().split('|'); + if (period) { + periodText.push(period.trim()); + getColWidth(period, colWidths); + } + if (text) { + p.textContent = text.trim(); + } + } + + if (isColorOrGradient(color)) { + colors.push(color); + row.firstElementChild.remove(); + } + row.parentElement.remove(); + side.append(row); + }); + textRow.append(left, right); + [textRow, addBarRow(), addBottomRow(periodText)].forEach((row) => fragment.append(row)); + updateColWidths(colWidths, fragment, el); + setColors(colors, fragment, el); + el.append(fragment); +} diff --git a/libs/utils/utils.js b/libs/utils/utils.js index 3b57b87e96..34fb6ad6c4 100644 --- a/libs/utils/utils.js +++ b/libs/utils/utils.js @@ -75,6 +75,7 @@ const MILO_BLOCKS = [ 'tabs', 'table-of-contents', 'text', + 'timeline', 'walls-io', 'table', 'table-metadata', From a88101b7a40c0070a77e08804e7626aeea81bde2 Mon Sep 17 00:00:00 2001 From: markpadbe Date: Tue, 10 Sep 2024 13:00:10 -0700 Subject: [PATCH 2/3] Update to match grid-width-10 --- libs/blocks/timeline/timeline.css | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/libs/blocks/timeline/timeline.css b/libs/blocks/timeline/timeline.css index 18f1de7c6d..ebf0842787 100644 --- a/libs/blocks/timeline/timeline.css +++ b/libs/blocks/timeline/timeline.css @@ -1,10 +1,12 @@ .timeline { box-sizing: border-box; - padding: 0 0 var(--spacing-xl) 0; - width: var(--grid-container-width); - max-width: 968px; + padding: 0 var(--grid-margins-width) var(--spacing-xl) var(--grid-margins-width); + width: 100%; margin: 0 auto; } +.dialog-modal .timeline { + padding: 0 var(--spacing-xl) var(--spacing-xl) var(--spacing-xl); +} .timeline .row { display: grid; @@ -123,20 +125,19 @@ } @media screen and (min-width: 600px) { - .timeline { - width: 100%; - padding: 0 var(--grid-margins-width) var(--spacing-xl) var(--grid-margins-width); - } - .dialog-modal .timeline { padding: 0 var(--spacing-xl) var(--spacing-xl) var(--spacing-xl); } } -@media screen and (min-width: 1200px) { +@media screen and (min-width:1120px) { .timeline { - padding: 0 0 var(--spacing-xxl) 0; - width: 968px; - max-width: 100%; + padding-left: calc((100vw - 1000px) / 2); + padding-right: calc((100vw - 1000px) / 2); + } + + .dialog-modal .timeline { + padding: 0 var(--spacing-xl) var(--spacing-xl) var(--spacing-xl); } } + From c1949f38b669fba7cd031bdad42d1be461154ea4 Mon Sep 17 00:00:00 2001 From: markpadbe Date: Thu, 19 Sep 2024 14:17:44 -0700 Subject: [PATCH 3/3] Remove from mep folder and add unit tests --- libs/mep/mwpw-143159/timeline/timeline.css | 142 ----------------- libs/mep/mwpw-143159/timeline/timeline.js | 153 ------------------- test/blocks/timeline/mocks/switchcolors.html | 25 +++ test/blocks/timeline/timeline.test.js | 77 ++++++++++ 4 files changed, 102 insertions(+), 295 deletions(-) delete mode 100644 libs/mep/mwpw-143159/timeline/timeline.css delete mode 100644 libs/mep/mwpw-143159/timeline/timeline.js create mode 100644 test/blocks/timeline/mocks/switchcolors.html create mode 100644 test/blocks/timeline/timeline.test.js diff --git a/libs/mep/mwpw-143159/timeline/timeline.css b/libs/mep/mwpw-143159/timeline/timeline.css deleted file mode 100644 index 18f1de7c6d..0000000000 --- a/libs/mep/mwpw-143159/timeline/timeline.css +++ /dev/null @@ -1,142 +0,0 @@ -.timeline { - box-sizing: border-box; - padding: 0 0 var(--spacing-xl) 0; - width: var(--grid-container-width); - max-width: 968px; - margin: 0 auto; -} - -.timeline .row { - display: grid; -} - -.timeline h1, -.timeline h2, -.timeline h3, -.timeline h4, -.timeline h5, -.timeline h6, -.timeline p { - color: var(--text-color); - margin: 0; - font-size: var(--type-body-xs-size); - line-height: var(--type-body-xs-lh); -} - -.timeline .row:nth-child(2)>div { - display: flex; - flex-direction: row; - align-items: center; -} - -.timeline .row:nth-of-type(1)>.right>div+div { - text-align: right; - display: flex; - flex-direction: column; - align-items: flex-end; -} - -.timeline .row:nth-of-type(1)>.left>div>* { - max-width: 100px; - padding-right: var(--spacing-m); -} - -.dark .timeline .row:nth-child(3)>div *, -.timeline.dark .row:nth-child(3)>div * { - color: var(--color-black); -} - -.timeline .row:nth-of-type(1)>.right>div+div>* { - max-width: 100px; -} - -.timeline .row:nth-of-type(1)>.right, -.timeline .row:nth-of-type(2)>.right { - display: grid; - justify-content: space-between; -} - -.timeline .row:nth-of-type(1)>.right { - grid-template-columns: minmax(110px, 1fr) 1fr; -} - -.timeline .row:nth-of-type(2)>.right { - grid-template-columns: 2px 2px; -} - -.timeline .row:nth-of-type(1)>.right>div:nth-of-type(1) { - max-width: 135px; - padding-right: var(--spacing-xxs); -} - -.timeline .bar { - height: 20px; - width: 2px; - border-radius: 1px; - margin: var(--spacing-xxs) 0; -} - -.timeline .row:nth-of-type(3) p { - text-align: center; - font-weight: 700; - padding: 4px var(--spacing-xxs); - height: 100%; - display: flex; - flex-direction: column; - justify-content: center; - border-radius: 4px; -} - -.timeline .row:nth-of-type(3) .left p { - margin-right: 1px; -} - -.timeline .row:nth-of-type(3) .right p { - margin-left: 3px; -} - -.dark .timeline .row:nth-child(1)>div>div>*, -.timeline.dark .row:nth-child(1)>div>div>* { - color: var(--color-white); -} - -[dir="rtl"] .timeline .row:nth-of-type(1)>.left>div>* { - padding: 0 0 0 var(--spacing-m); - text-align: right; -} - -[dir="rtl"] .timeline .row:nth-of-type(1)>.right>div+div { - padding: 0 0 var(--spacing-xxs) 0; - text-align: left; -} - -[dir="rtl"] .timeline .row:nth-of-type(3) .left p { - margin: 0 0 0 1px; -} - -[dir="rtl"] .timeline .row:nth-of-type(3) .right p { - margin: 0 3px 0 0; -} - -[dir="rtl"] .timeline .row:nth-of-type(1)>.right>div:nth-of-type(1) { - padding: 0 0 0 var(--spacing-xxs); -} - -@media screen and (min-width: 600px) { - .timeline { - width: 100%; - padding: 0 var(--grid-margins-width) var(--spacing-xl) var(--grid-margins-width); - } - - .dialog-modal .timeline { - padding: 0 var(--spacing-xl) var(--spacing-xl) var(--spacing-xl); - } -} - -@media screen and (min-width: 1200px) { - .timeline { - padding: 0 0 var(--spacing-xxl) 0; - width: 968px; - max-width: 100%; - } -} diff --git a/libs/mep/mwpw-143159/timeline/timeline.js b/libs/mep/mwpw-143159/timeline/timeline.js deleted file mode 100644 index 8322c09592..0000000000 --- a/libs/mep/mwpw-143159/timeline/timeline.js +++ /dev/null @@ -1,153 +0,0 @@ -import { createTag } from '../../../utils/utils.js'; - -function isColor(str) { - const hexRegex = /^#(?:[0-9a-fA-F]{3}){1,2}$/; - const rgbRegex = /^rgb\(\s*\d{1,3}\s*,\s*\d{1,3}\s*,\s*\d{1,3}\s*\)$/; - return hexRegex.test(str) || rgbRegex.test(str); -} - -function isGradient(str) { - return str.startsWith('linear-gradient'); -} - -function isColorOrGradient(str) { - return isColor(str) || isGradient(str); -} - -function getColWidth(text, colWidths) { - const numRegex = /\b\d{1,3}\b/; - colWidths.push((text.match(numRegex) || [])[0]); -} -function createRow() { - return [createTag('div', { class: 'row' }), - createTag('div', { class: 'left' }), - createTag('div', { class: 'right' }), - ]; -} -function createBars(index) { - return index === 0 - ? [createTag('div', { class: 'bar' })] : [createTag('div', { class: 'bar' }), createTag('div', { class: 'bar' })]; -} -function addBarRow() { - const [barRow, left, right] = createRow(); - const sides = [left, right]; - sides.forEach((text, index) => { - sides[index].append(...createBars(index)); - barRow.append(sides[index]); - }); - return barRow; -} -function addBottomRow(periodText) { - const [periodRow, left, right] = createRow(); - const sides = [left, right]; - periodText.forEach((text, index) => { - sides[index].append(createTag('p', { class: 'period body-s' }, text)); - periodRow.append(sides[index]); - }); - return periodRow; -} - -function setBG(el, color) { - el.style.background = color; -} - -function updateForRTL(lgStr, el) { - if (el.closest('[dir="rtl"]')) { - return lgStr.replace(/to right|to left|90deg|180deg|turn 0.25|turn 0.75/g, (match) => { - const converter = { - 'turn 0.25': 'turn 0.75', - 'turn 0.75': 'turn 0.25', - '90deg': '180deg', - '180deg': '90deg', - 'to right': 'to left', - 'to left': 'to right', - }; - - return converter[match]; - }); - } - return lgStr; -} -function setColors(colors, fragment, el) { - const barEls = fragment.querySelectorAll('.bar'); - const periodEls = fragment.querySelectorAll('.period'); - if (colors?.length === 2 && isColorOrGradient(colors[0]) && isColorOrGradient(colors[1])) { - if (barEls.length === 3 || periodEls.length === 2) { - const leftColor = colors[0]; - const rightColor = colors[1]; - let firstBar; let secondBar; let thirdBar; - if (isGradient(leftColor)) { - leftColor.split(' ').forEach((color) => { - if (isColor(color) && !firstBar) { - firstBar = color; - setBG(barEls[0], firstBar); - } else if (isColor(color)) { - secondBar = color; - setBG(barEls[1], secondBar); - } - }); - } else { - setBG(barEls[0], leftColor); - setBG(barEls[1], leftColor); - } - if (isGradient(rightColor)) { - leftColor.split(' ').forEach((color) => { - if (isColor(color) && !thirdBar) { - thirdBar = color; - setBG(barEls[2], thirdBar); - } - }); - } else { - setBG(barEls[2], rightColor); - } - setBG(periodEls[0], updateForRTL(leftColor, el)); - setBG(periodEls[1], updateForRTL(rightColor, el)); - } - } -} - -function colWidthsNotValid(colWidths) { - return (colWidths.length !== 2 || colWidths.some((value) => Number.isNaN(value))); -} -function updateColWidths(colWidths, fragment) { - if (colWidthsNotValid(colWidths)) return; - const total = Number(colWidths[0]) + Number(colWidths[1]); - const right = Math.floor((Number(colWidths[1]) / total) * 10000) / 100; - const colString = `1fr minmax(${String(right)}%, 150px)`; - fragment.querySelectorAll('.row').forEach((row) => { - row.style.gridTemplateColumns = colString; - }); -} -export default function init(el) { - const fragment = document.createDocumentFragment(); - const [textRow, left, right] = createRow(); - const rows = el.querySelectorAll(':scope > div > div'); - const colors = []; const periodText = []; const colWidths = []; - rows.forEach((row, index) => { - const side = index === 0 ? left : right; - const color = row.firstElementChild?.textContent?.trim(); - const p = row.querySelector(':scope > p:last-child'); - if (p) { - const [text, period] = p.textContent.trim().split('|'); - if (period) { - periodText.push(period.trim()); - getColWidth(period, colWidths); - } - if (text) { - p.textContent = text.trim(); - } - } - - if (isColorOrGradient(color)) { - colors.push(color); - row.firstElementChild.remove(); - } - row.parentElement.remove(); - side.append(row); - }); - textRow.append(left, right); - [textRow, addBarRow(), addBottomRow(periodText)].forEach((row) => fragment.append(row)); - updateColWidths(colWidths, fragment, el); - setColors(colors, fragment, el); - el.append(fragment); -} diff --git a/test/blocks/timeline/mocks/switchcolors.html b/test/blocks/timeline/mocks/switchcolors.html new file mode 100644 index 0000000000..13e81224b7 --- /dev/null +++ b/test/blocks/timeline/mocks/switchcolors.html @@ -0,0 +1,25 @@ + +
+
+
+

#FFCE2E

+

Day 1

+

If you start your free trial today | 7-day free trial

+
+
+
+
+

linear-gradient(to right, #E63888 0, #E9749A 100%)

+

Day 8

+

Your subscription starts and billing begins | 14-day full refund period

+
+
+
+
+

Day 21

+

Full refund period ends

+
+
+
+ + diff --git a/test/blocks/timeline/timeline.test.js b/test/blocks/timeline/timeline.test.js new file mode 100644 index 0000000000..204f3719a6 --- /dev/null +++ b/test/blocks/timeline/timeline.test.js @@ -0,0 +1,77 @@ +import { readFile } from '@web/test-runner-commands'; +import { expect } from '@esm-bundle/chai'; +import { setConfig } from '../../../libs/utils/utils.js'; + +const config = { codeRoot: '/libs' }; +setConfig(config); + +const { default: init } = await import('../../../libs/blocks/timeline/timeline.js'); + +describe('Timeline', () => { + beforeEach(async () => { + document.body.innerHTML = await readFile({ path: './mocks/body.html' }); + }); + + afterEach(() => { + document.body.innerHTML = ''; + }); + + it('has 3 headers', async () => { + const timelineEl = document.querySelector('.timeline'); + init(timelineEl); + const headers = timelineEl.querySelectorAll('.timeline h3'); + expect(headers[0].textContent).to.equal('Day 1'); + expect(headers[1].textContent).to.equal('Day 8'); + expect(headers[2].textContent).to.equal('Day 21'); + }); + it('has 3 descriptions', async () => { + const timelineEl = document.querySelector('.timeline'); + init(timelineEl); + const descriptions = timelineEl.querySelectorAll('.timeline h3 + p'); + + expect(descriptions[0].textContent).to.equal('If you start your free trial today'); + expect(descriptions[1].textContent).to.equal('Your subscription starts and billing begins'); + expect(descriptions[2].textContent).to.equal('Full refund period ends'); + }); + it('has a payment period and a refund period section ', async () => { + const timelineEl = document.querySelector('.timeline'); + init(timelineEl); + const trialPeriod = timelineEl.querySelector('.row .left .period'); + const refundPeriod = timelineEl.querySelector('.row .right .period'); + + expect(trialPeriod.textContent).to.equal('7-day free trial'); + expect(refundPeriod.textContent).to.equal('14-day full refund period'); + expect(trialPeriod.style.background.includes('to right')).to.true; + }); + it('it sets bar background colors based on colors in free trial and refund period section', async () => { + const timelineEl = document.querySelector('.timeline'); + init(timelineEl); + const bars = timelineEl.querySelectorAll('.bar'); + + expect(bars[0].style.backgroundColor).to.equal('rgb(230, 56, 136)'); + expect(bars[1].style.backgroundColor).to.equal('rgb(233, 116, 154)'); + expect(bars[2].style.backgroundColor).to.equal('rgb(255, 206, 46)'); + }); + it('updates background linear gradient for rtl', async () => { + const timelineEl = document.querySelector('.timeline'); + timelineEl.parentElement.setAttribute('dir', 'rtl'); + init(timelineEl); + const trialPeriod = timelineEl.querySelector('.row .left .period'); + expect(trialPeriod.style.background.includes('to left')).to.be.true; + }); + describe('Timeline', () => { + beforeEach(async () => { + document.body.innerHTML = await readFile({ path: './mocks/switchcolors.html' }); + }); + afterEach(() => { + document.body.innerHTML = ''; + }); + it('handles linear-gradient for either side', async () => { + const timelineEl = document.querySelector('.timeline'); + init(timelineEl); + const refundPeriod = timelineEl.querySelector('.row .right .period'); + expect(refundPeriod.textContent).to.equal('14-day full refund period'); + expect(refundPeriod.style.background.includes('to left')).to.true; + }); + }); +});