From f86c248021b5d33aa4b8383c2f9c935bc1e86b49 Mon Sep 17 00:00:00 2001 From: Owen Buckley Date: Thu, 26 Oct 2023 21:16:34 -0400 Subject: [PATCH] add basic base path test cases for develop and serve commands --- .../develop.config.base-path.spec.js | 301 ++++++++++++++++++ .../greenwood.config.js | 3 + .../develop.config.base-path/package.json | 4 + .../src/assets/logo.png | Bin 0 -> 2171 bytes .../src/components/card.js | 22 ++ .../src/pages/index.html | 16 + .../src/styles/main.css | 3 + .../greenwood.config.js | 3 + .../serve.config.base-path.spec.js | 279 ++++++++++++++++ .../src/assets/logo.png | Bin 0 -> 2171 bytes .../src/components/card.js | 22 ++ .../src/pages/index.html | 16 + .../src/styles/main.css | 3 + 13 files changed, 672 insertions(+) create mode 100644 packages/cli/test/cases/develop.config.base-path/develop.config.base-path.spec.js create mode 100644 packages/cli/test/cases/develop.config.base-path/greenwood.config.js create mode 100644 packages/cli/test/cases/develop.config.base-path/package.json create mode 100644 packages/cli/test/cases/develop.config.base-path/src/assets/logo.png create mode 100644 packages/cli/test/cases/develop.config.base-path/src/components/card.js create mode 100644 packages/cli/test/cases/develop.config.base-path/src/pages/index.html create mode 100644 packages/cli/test/cases/develop.config.base-path/src/styles/main.css create mode 100644 packages/cli/test/cases/serve.config.base-path/greenwood.config.js create mode 100644 packages/cli/test/cases/serve.config.base-path/serve.config.base-path.spec.js create mode 100644 packages/cli/test/cases/serve.config.base-path/src/assets/logo.png create mode 100644 packages/cli/test/cases/serve.config.base-path/src/components/card.js create mode 100644 packages/cli/test/cases/serve.config.base-path/src/pages/index.html create mode 100644 packages/cli/test/cases/serve.config.base-path/src/styles/main.css diff --git a/packages/cli/test/cases/develop.config.base-path/develop.config.base-path.spec.js b/packages/cli/test/cases/develop.config.base-path/develop.config.base-path.spec.js new file mode 100644 index 000000000..95596f459 --- /dev/null +++ b/packages/cli/test/cases/develop.config.base-path/develop.config.base-path.spec.js @@ -0,0 +1,301 @@ +/* + * Use Case + * Run Greenwood develop command with no config. + * + * User Result + * Should start the development server and render a bare bones Greenwood build. + * + * User Command + * greenwood develop + * + * User Config + * devServer: { + * basePath: '/my-path' + * } + * + * User Workspace + * src/ + * assets/ + * logo.png + * components/ + * card.js + * pages/ + * index.html + * styles/ + * main.css + * package.json + */ +import chai from 'chai'; +import { JSDOM } from 'jsdom'; +import path from 'path'; +import { getSetupFiles } from '../../../../../test/utils.js'; +import request from 'request'; +import { Runner } from 'gallinago'; +import { fileURLToPath, URL } from 'url'; + +const expect = chai.expect; + +describe('Develop Greenwood With: ', function() { + const LABEL = 'Base Path Configuration'; + const cliPath = path.join(process.cwd(), 'packages/cli/src/index.js'); + const outputPath = fileURLToPath(new URL('.', import.meta.url)); + const hostname = 'http://localhost'; + const port = 1984; + const basePath = '/my-path'; + let runner; + + before(function() { + this.context = { + hostname: `${hostname}:${port}` + }; + runner = new Runner(); + }); + + describe(LABEL, function() { + + before(async function() { + + await runner.setup(outputPath, [ + ...getSetupFiles(outputPath) + ]); + + return new Promise(async (resolve) => { + setTimeout(() => { + resolve(); + }, 5000); + + await runner.runCommand(cliPath, 'develop'); + }); + }); + + describe('Develop command specific HTML behaviors', function() { + let response = {}; + let dom; + + before(async function() { + return new Promise((resolve, reject) => { + request.get({ + url: `http://127.0.0.1:${port}${basePath}/`, + headers: { + accept: 'text/html' + } + }, (err, res, body) => { + if (err) { + reject(); + } + + response = res; + dom = new JSDOM(body); + + resolve(); + }); + }); + }); + + it('should return the correct content type', function(done) { + expect(response.headers['content-type']).to.contain('text/html'); + done(); + }); + + it('should return a 200', function(done) { + expect(response.statusCode).to.equal(200); + + done(); + }); + + it('should have the expected heading tag in the DOM', function(done) { + const headings = Array.from(dom.window.document.querySelectorAll('body > h1')); + + expect(headings.length).to.equal(1); + expect(headings[0].textContent).to.equal('Hello World'); + + done(); + }); + + it('should have the expected tag in the DOM', function(done) { + const cards = Array.from(dom.window.document.querySelectorAll('body > app-card')); + + expect(cards.length).to.equal(1); + + done(); + }); + }); + + describe('Develop command specific JavaScript behaviors for user authored custom element', function() { + let response = {}; + + before(async function() { + return new Promise((resolve, reject) => { + request.get(`${hostname}:${port}${basePath}/components/card.js`, (err, res, body) => { + if (err) { + reject(); + } + + response = res; + response.body = body; + + resolve(); + }); + }); + }); + + it('should return a 200 status', function(done) { + expect(response.statusCode).to.equal(200); + done(); + }); + + it('should return the correct content type', function(done) { + expect(response.headers['content-type']).to.contain('text/javascript'); + done(); + }); + + it('should return the correct response body', function(done) { + expect(response.body).to.contain('class Card extends HTMLElement'); + done(); + }); + }); + + describe('Develop command specific CSS behaviors', function() { + let response = {}; + + before(async function() { + return new Promise((resolve, reject) => { + request.get(`${hostname}:${port}${basePath}/styles/main.css`, (err, res, body) => { + if (err) { + reject(); + } + + response = res; + response.body = body; + + resolve(); + }); + }); + }); + + it('should eturn a 200 status', function(done) { + expect(response.statusCode).to.equal(200); + done(); + }); + + it('should return the correct content type', function(done) { + expect(response.headers['content-type']).to.contain('text/css'); + done(); + }); + + it('should return the correct response body', function(done) { + expect(response.body).to.contain('color: blue;'); + done(); + }); + }); + + describe('Develop command with image (png) specific behavior', function() { + const ext = 'png'; + let response = {}; + + before(async function() { + return new Promise((resolve, reject) => { + + request.get(`${hostname}:${port}${basePath}/assets/logo.${ext}`, (err, res, body) => { + if (err) { + reject(); + } + + response = res; + response.body = body; + + resolve(); + }); + }); + }); + + it('should return a 200 status', function(done) { + expect(response.statusCode).to.equal(200); + done(); + }); + + it('should return the correct content type', function(done) { + expect(response.headers['content-type']).to.contain(`image/${ext}`); + done(); + }); + + it('should return binary data', function(done) { + expect(response.body).to.contain('PNG'); + done(); + }); + }); + + // TODO + // proxies to https://jsonplaceholder.typicode.com/posts via greenwood.config.js + // describe('Develop command with dev proxy', function() { + // let response = {}; + + // before(async function() { + // return new Promise((resolve, reject) => { + // request.get(`${hostname}:${port}/posts?id=7`, (err, res, body) => { + // if (err) { + // reject(); + // } + + // response = res; + // response.body = JSON.parse(body); + + // resolve(); + // }); + // }); + // }); + + // it('should return a 200 status', function(done) { + // expect(response.statusCode).to.equal(200); + // done(); + // }); + + // it('should return the correct content type', function(done) { + // expect(response.headers['content-type']).to.contain('application/json'); + // done(); + // }); + + // it('should return the correct response body', function(done) { + // expect(response.body).to.have.lengthOf(1); + // done(); + // }); + // }); + + // TODO + // describe('Develop command with API specific behaviors', function() { + // const name = 'Greenwood'; + // let response = {}; + // let data = {}; + + // before(async function() { + // response = await fetch(`${hostname}:${port}/api/greeting?name=${name}`); + + // data = await response.json(); + // }); + + // it('should return a 200 status', function(done) { + // expect(response.ok).to.equal(true); + // expect(response.status).to.equal(200); + // done(); + // }); + + // it('should return the correct content type', function(done) { + // expect(response.headers.get('content-type')).to.equal('application/json; charset=utf-8'); + // done(); + // }); + + // it('should return the correct response body', function(done) { + // expect(data.message).to.equal(`Hello ${name}!!!`); + // done(); + // }); + // }); + }); + + after(function() { + runner.stopCommand(); + runner.teardown([ + path.join(outputPath, '.greenwood'), + path.join(outputPath, 'node_modules') + ]); + }); +}); \ No newline at end of file diff --git a/packages/cli/test/cases/develop.config.base-path/greenwood.config.js b/packages/cli/test/cases/develop.config.base-path/greenwood.config.js new file mode 100644 index 000000000..95cf3b707 --- /dev/null +++ b/packages/cli/test/cases/develop.config.base-path/greenwood.config.js @@ -0,0 +1,3 @@ +export default { + basePath: '/my-path' +}; \ No newline at end of file diff --git a/packages/cli/test/cases/develop.config.base-path/package.json b/packages/cli/test/cases/develop.config.base-path/package.json new file mode 100644 index 000000000..ab6239c28 --- /dev/null +++ b/packages/cli/test/cases/develop.config.base-path/package.json @@ -0,0 +1,4 @@ +{ + "name": "test-develop-command-config-base-path", + "type": "module" +} \ No newline at end of file diff --git a/packages/cli/test/cases/develop.config.base-path/src/assets/logo.png b/packages/cli/test/cases/develop.config.base-path/src/assets/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..786360832aca0b004303207c8de025786573ff12 GIT binary patch literal 2171 zcmV->2!!{EP)9J#33pYKK;ruZV}D zb##(ls=%LpnP;cGnT4QnUxQ6?kzrYTMV+*aj;Vi)sC>iOjB}D-v(iPh&|}Qsq`uaB zV1Gtofk;<*KDN?mvC%)b)K7_~dw!Z~$=jvD*n?1VG-ZQKh@x_Ai&VAHVSbrsS9Uy{ z#!O6bFT&bsYl>8Klw!KoXSvjFd6i$j*L!b_Su>7Gc9dYO!=S|5jf${Ll)Ot#ZZWXV zR++Jhy46^%&33)lbi&$yw_WQn`=^ZHnY(~ zqr_{HwOW3lQM}h-hpAhh#!SN6gtgI8Qj=H9-k!?dp0m+Ni>7)5lk#6OX^F{#j6&f}m%g*}b5E-sBhPIfSWs4IM~$liI+Nj~UKm=xdR&is?W{SGj5+{(_((pd~1kVs(z>iAy1VV9d5vBT-*-r~uAO-`g`JLtj79lo3oE+$|=y0+w zrOl0PG7%3;bHBr(r)78*_xPe26>h$$6?!v^5Ph1y0 zNj5jriGhnnL^=W#Ze zpa^o7d*K<$V1XKv%+qZ60bDLDmPORWvYV@{Bo-CK(V3n*U#A4*Eft}PP`OJG-dSUq ztEIvZM>M3=ozXzzSB?cLxO6)z#tMeJv;HM*Pz=S=%(VrRb*tN7S!LUtAmn=S$7MEh zH_u5A5`8MM5I?kKxk;fI;taN+{4F%{r@Bz1R*?P37B5(vGl3{FLHw2(pgWqrGwmQz zfF3V`BW*f{lg{Ag!iLS1S&)85N!l(8bZkrBkNneM8q%<_46Vzh{# zh}cf==OZV*ytrR$WAFi$=T3}!KJTzaW#){??i+;~tM-mOza0J{z;;MpZEz+Pp=)s# z&z}y+-BsKK)wdVQptoRjMFZ5wK*CLh979oI_?RRt_+A>HQ2e&W3C1b*uaZau_p)R{ z%yO6$`(ekPDqBg34W%Zb>~-k%B5351^iAF3{-!Hr+iy*%Sk1+{<#?0TBcVPq_VeZ7 zN8MCVXM(d$A_}a)b;>bGjxLS!0+TjA;aSc2_ychg@qe z5Z*t1Zi&wzNboW2aNgtx*9!t0u41Db#I^=x#frCHCV{ma)7S}#wP1vqud$G7_$pHs zvdhewmp_rj7zz~?xI<+`OBashXCN-Y+!Y3X7A4;J)*~-E1PC;W;(NWqk89;lmD(7= xK5^FL^3=u%U}?JGJ$Lx02jMQk|4;Cr%RhBN)O-8hSTFzp002ovPDHLkV1iX3Cz=2N literal 0 HcmV?d00001 diff --git a/packages/cli/test/cases/develop.config.base-path/src/components/card.js b/packages/cli/test/cases/develop.config.base-path/src/components/card.js new file mode 100644 index 000000000..65a013b75 --- /dev/null +++ b/packages/cli/test/cases/develop.config.base-path/src/components/card.js @@ -0,0 +1,22 @@ +const template = document.createElement('template'); + +template.innerHTML = ` +
+ My default title + +
+
+`; + +class Card extends HTMLElement { + connectedCallback() { + if (!this.shadowRoot) { + this.attachShadow({ mode: 'open' }); + this.shadowRoot.appendChild(template.content.cloneNode(true)); + } + } +} + +customElements.define('app-card', Card); + +export default Card; \ No newline at end of file diff --git a/packages/cli/test/cases/develop.config.base-path/src/pages/index.html b/packages/cli/test/cases/develop.config.base-path/src/pages/index.html new file mode 100644 index 000000000..9b506b6cc --- /dev/null +++ b/packages/cli/test/cases/develop.config.base-path/src/pages/index.html @@ -0,0 +1,16 @@ + + + + + + + + +

Hello World

+ +

Greenwood Logo

+ Greenwood Logo +
+ + + \ No newline at end of file diff --git a/packages/cli/test/cases/develop.config.base-path/src/styles/main.css b/packages/cli/test/cases/develop.config.base-path/src/styles/main.css new file mode 100644 index 000000000..9a7b45f93 --- /dev/null +++ b/packages/cli/test/cases/develop.config.base-path/src/styles/main.css @@ -0,0 +1,3 @@ +* { + color: blue; +} \ No newline at end of file diff --git a/packages/cli/test/cases/serve.config.base-path/greenwood.config.js b/packages/cli/test/cases/serve.config.base-path/greenwood.config.js new file mode 100644 index 000000000..95cf3b707 --- /dev/null +++ b/packages/cli/test/cases/serve.config.base-path/greenwood.config.js @@ -0,0 +1,3 @@ +export default { + basePath: '/my-path' +}; \ No newline at end of file diff --git a/packages/cli/test/cases/serve.config.base-path/serve.config.base-path.spec.js b/packages/cli/test/cases/serve.config.base-path/serve.config.base-path.spec.js new file mode 100644 index 000000000..612df879e --- /dev/null +++ b/packages/cli/test/cases/serve.config.base-path/serve.config.base-path.spec.js @@ -0,0 +1,279 @@ +/* + * Use Case + * Run Greenwood serve command with no config. + * + * User Result + * Should start the production server and render a bare bones Greenwood build. + * + * User Command + * greenwood serve + * + * User Config + * devServer: { + * basePath: '/my-path' + * } + * + * User Workspace + * src/ + * assets/ + * logo.png + * components/ + * card.js + * pages/ + * index.html + * styles/ + * main.css + * package.json + */ +import chai from 'chai'; +import { JSDOM } from 'jsdom'; +import path from 'path'; +import { getSetupFiles, getOutputTeardownFiles } from '../../../../../test/utils.js'; +import request from 'request'; +import { Runner } from 'gallinago'; +import { fileURLToPath, URL } from 'url'; + +const expect = chai.expect; + +describe('Serve Greenwood With: ', function() { + const LABEL = 'Base Path Configuration'; + const cliPath = path.join(process.cwd(), 'packages/cli/src/index.js'); + const outputPath = fileURLToPath(new URL('.', import.meta.url)); + const hostname = 'http://127.0.0.1:8080'; + const basePath = '/my-path'; + const jsHash = '4bcc801e'; + const cssHash = '1454013616'; + let runner; + + before(function() { + this.context = { + hostname + }; + runner = new Runner(); + }); + + describe(LABEL, function() { + + before(async function() { + await runner.setup(outputPath, getSetupFiles(outputPath)); + await runner.runCommand(cliPath, 'build'); + + return new Promise(async (resolve) => { + setTimeout(() => { + resolve(); + }, 10000); + + await runner.runCommand(cliPath, 'serve'); + }); + }); + + describe('Serve command specific HTML behaviors', function() { + let response = {}; + let dom; + + before(async function() { + return new Promise((resolve, reject) => { + request.get({ + url: `${hostname}${basePath}/`, + headers: { + accept: 'text/html' + } + }, (err, res, body) => { + if (err) { + reject(); + } + + response = res; + dom = new JSDOM(body); + + resolve(); + }); + }); + }); + + it('should return the correct content type', function(done) { + expect(response.headers['content-type']).to.contain('text/html'); + done(); + }); + + it('should return a 200', function(done) { + expect(response.statusCode).to.equal(200); + + done(); + }); + + it('should have the expected heading tag in the DOM', function(done) { + const headings = Array.from(dom.window.document.querySelectorAll('body > h1')); + + expect(headings.length).to.equal(1); + expect(headings[0].textContent).to.equal('Hello World'); + + done(); + }); + + it('should have the expected tag in the DOM', function(done) { + const cards = Array.from(dom.window.document.querySelectorAll('body > app-card')); + + expect(cards.length).to.equal(1); + + done(); + }); + + it('should have the correct script link preload tag path in the DOM', function(done) { + const links = Array + .from(dom.window.document.querySelectorAll('head > link')) + .filter(link => link.getAttribute('as') === 'script'); + + expect(links.length).to.equal(1); + expect(links[0].getAttribute('href')).to.equal(`${basePath}/card.${jsHash}.js`); + + done(); + }); + + it('should have the correct script tag path in the DOM', function(done) { + const scripts = Array.from(dom.window.document.querySelectorAll('head > script')); + + expect(scripts.length).to.equal(1); + expect(scripts[0].getAttribute('src')).to.equal(`${basePath}/card.${jsHash}.js`); + + done(); + }); + + // + it('should have the correct style preload tag path in the DOM', function(done) { + const links = Array + .from(dom.window.document.querySelectorAll('head > link')) + .filter(link => link.getAttribute('as') === 'style'); + + expect(links.length).to.equal(1); + expect(links[0].getAttribute('href')).to.equal(`${basePath}/styles/main.${cssHash}.css`); + + done(); + }); + + it('should have the correct link tag for the stylesheet in the DOM', function(done) { + const styles = Array + .from(dom.window.document.querySelectorAll('head > link')) + .filter(link => link.getAttribute('rel') === 'stylesheet'); + + expect(styles.length).to.equal(1); + expect(styles[0].getAttribute('href')).to.equal(`${basePath}/styles/main.${cssHash}.css`); + + done(); + }); + }); + + describe('Serve command specific JavaScript behaviors for user authored custom element', function() { + let response = {}; + + before(async function() { + return new Promise((resolve, reject) => { + request.get(`${hostname}${basePath}/card.${jsHash}.js`, (err, res, body) => { + if (err) { + reject(); + } + + response = res; + response.body = body; + + resolve(); + }); + }); + }); + + it('should return a 200 status', function(done) { + expect(response.statusCode).to.equal(200); + done(); + }); + + it('should return the correct content type', function(done) { + expect(response.headers['content-type']).to.contain('text/javascript'); + done(); + }); + + it('should return the correct response body', function(done) { + expect(response.body).to.contain('class t extends HTMLElement'); + done(); + }); + }); + + describe('Serve command specific CSS behaviors', function() { + let response = {}; + + before(async function() { + return new Promise((resolve, reject) => { + request.get(`${hostname}${basePath}/styles/main.${cssHash}.css`, (err, res, body) => { + if (err) { + reject(); + } + + response = res; + response.body = body; + + resolve(); + }); + }); + }); + + it('should return a 200 status', function(done) { + expect(response.statusCode).to.equal(200); + done(); + }); + + it('should return the correct content type', function(done) { + expect(response.headers['content-type']).to.contain('text/css'); + done(); + }); + + it('should return the correct response body', function(done) { + expect(response.body).to.contain('*{color:blue}'); + done(); + }); + }); + + describe('Serve command with image (png) specific behavior', function() { + const ext = 'png'; + let response = {}; + + before(async function() { + return new Promise((resolve, reject) => { + + request.get(`${hostname}${basePath}/assets/logo.${ext}`, (err, res, body) => { + if (err) { + reject(); + } + + response = res; + response.body = body; + + resolve(); + }); + }); + }); + + it('should return a 200 status', function(done) { + expect(response.statusCode).to.equal(200); + done(); + }); + + it('should return the correct content type', function(done) { + expect(response.headers['content-type']).to.contain(`image/${ext}`); + done(); + }); + + it('should return binary data', function(done) { + expect(response.body).to.contain('PNG'); + done(); + }); + }); + + // TODO + // dev server proxy + // API end[points + }); + + after(function() { + runner.teardown(getOutputTeardownFiles(outputPath)); + runner.stopCommand(); + }); +}); \ No newline at end of file diff --git a/packages/cli/test/cases/serve.config.base-path/src/assets/logo.png b/packages/cli/test/cases/serve.config.base-path/src/assets/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..786360832aca0b004303207c8de025786573ff12 GIT binary patch literal 2171 zcmV->2!!{EP)9J#33pYKK;ruZV}D zb##(ls=%LpnP;cGnT4QnUxQ6?kzrYTMV+*aj;Vi)sC>iOjB}D-v(iPh&|}Qsq`uaB zV1Gtofk;<*KDN?mvC%)b)K7_~dw!Z~$=jvD*n?1VG-ZQKh@x_Ai&VAHVSbrsS9Uy{ z#!O6bFT&bsYl>8Klw!KoXSvjFd6i$j*L!b_Su>7Gc9dYO!=S|5jf${Ll)Ot#ZZWXV zR++Jhy46^%&33)lbi&$yw_WQn`=^ZHnY(~ zqr_{HwOW3lQM}h-hpAhh#!SN6gtgI8Qj=H9-k!?dp0m+Ni>7)5lk#6OX^F{#j6&f}m%g*}b5E-sBhPIfSWs4IM~$liI+Nj~UKm=xdR&is?W{SGj5+{(_((pd~1kVs(z>iAy1VV9d5vBT-*-r~uAO-`g`JLtj79lo3oE+$|=y0+w zrOl0PG7%3;bHBr(r)78*_xPe26>h$$6?!v^5Ph1y0 zNj5jriGhnnL^=W#Ze zpa^o7d*K<$V1XKv%+qZ60bDLDmPORWvYV@{Bo-CK(V3n*U#A4*Eft}PP`OJG-dSUq ztEIvZM>M3=ozXzzSB?cLxO6)z#tMeJv;HM*Pz=S=%(VrRb*tN7S!LUtAmn=S$7MEh zH_u5A5`8MM5I?kKxk;fI;taN+{4F%{r@Bz1R*?P37B5(vGl3{FLHw2(pgWqrGwmQz zfF3V`BW*f{lg{Ag!iLS1S&)85N!l(8bZkrBkNneM8q%<_46Vzh{# zh}cf==OZV*ytrR$WAFi$=T3}!KJTzaW#){??i+;~tM-mOza0J{z;;MpZEz+Pp=)s# z&z}y+-BsKK)wdVQptoRjMFZ5wK*CLh979oI_?RRt_+A>HQ2e&W3C1b*uaZau_p)R{ z%yO6$`(ekPDqBg34W%Zb>~-k%B5351^iAF3{-!Hr+iy*%Sk1+{<#?0TBcVPq_VeZ7 zN8MCVXM(d$A_}a)b;>bGjxLS!0+TjA;aSc2_ychg@qe z5Z*t1Zi&wzNboW2aNgtx*9!t0u41Db#I^=x#frCHCV{ma)7S}#wP1vqud$G7_$pHs zvdhewmp_rj7zz~?xI<+`OBashXCN-Y+!Y3X7A4;J)*~-E1PC;W;(NWqk89;lmD(7= xK5^FL^3=u%U}?JGJ$Lx02jMQk|4;Cr%RhBN)O-8hSTFzp002ovPDHLkV1iX3Cz=2N literal 0 HcmV?d00001 diff --git a/packages/cli/test/cases/serve.config.base-path/src/components/card.js b/packages/cli/test/cases/serve.config.base-path/src/components/card.js new file mode 100644 index 000000000..65a013b75 --- /dev/null +++ b/packages/cli/test/cases/serve.config.base-path/src/components/card.js @@ -0,0 +1,22 @@ +const template = document.createElement('template'); + +template.innerHTML = ` +
+ My default title + +
+
+`; + +class Card extends HTMLElement { + connectedCallback() { + if (!this.shadowRoot) { + this.attachShadow({ mode: 'open' }); + this.shadowRoot.appendChild(template.content.cloneNode(true)); + } + } +} + +customElements.define('app-card', Card); + +export default Card; \ No newline at end of file diff --git a/packages/cli/test/cases/serve.config.base-path/src/pages/index.html b/packages/cli/test/cases/serve.config.base-path/src/pages/index.html new file mode 100644 index 000000000..9b506b6cc --- /dev/null +++ b/packages/cli/test/cases/serve.config.base-path/src/pages/index.html @@ -0,0 +1,16 @@ + + + + + + + + +

Hello World

+ +

Greenwood Logo

+ Greenwood Logo +
+ + + \ No newline at end of file diff --git a/packages/cli/test/cases/serve.config.base-path/src/styles/main.css b/packages/cli/test/cases/serve.config.base-path/src/styles/main.css new file mode 100644 index 000000000..9a7b45f93 --- /dev/null +++ b/packages/cli/test/cases/serve.config.base-path/src/styles/main.css @@ -0,0 +1,3 @@ +* { + color: blue; +} \ No newline at end of file