├── .github └── workflows │ └── verify.yml ├── .gitignore ├── guides ├── dev-server │ ├── getting-started │ │ ├── demo │ │ │ └── index.html │ │ ├── package-lock.json │ │ └── package.json │ ├── loading-modules │ │ ├── demo │ │ │ └── index.html │ │ ├── package-lock.json │ │ ├── package.json │ │ └── src │ │ │ └── message.js │ ├── proxy-to-other-servers │ │ ├── api-server.mjs │ │ ├── demo │ │ │ └── index.html │ │ ├── package-lock.json │ │ ├── package.json │ │ └── web-dev-server.config.mjs │ ├── typescript-and-jsx │ │ ├── demo │ │ │ ├── jsx.html │ │ │ └── ts.html │ │ ├── package-lock.json │ │ ├── package.json │ │ ├── src │ │ │ ├── app.jsx │ │ │ └── logger.ts │ │ ├── web-dev-server.jsx.mjs │ │ └── web-dev-server.ts.mjs │ ├── using-plugins │ │ ├── demo │ │ │ ├── babel.html │ │ │ ├── commonjs.html │ │ │ └── index.html │ │ ├── package-lock.json │ │ ├── package.json │ │ ├── src │ │ │ ├── app.jsx │ │ │ └── logger.js │ │ ├── web-dev-server.babel.mjs │ │ ├── web-dev-server.commonjs.mjs │ │ └── web-dev-server.config.mjs │ └── writing-plugins │ │ ├── demo │ │ ├── env.html │ │ └── index.html │ │ ├── package-lock.json │ │ ├── package.json │ │ ├── src │ │ └── logger.js │ │ ├── web-dev-server.env.mjs │ │ └── web-dev-server.inject.mjs └── test-runner │ ├── getting-started │ ├── package-lock.json │ ├── package.json │ ├── src │ │ └── sum.js │ └── test │ │ └── sum.test.js │ ├── playwright │ ├── package-lock.json │ ├── package.json │ ├── src │ │ ├── calc.js │ │ └── sum.js │ └── test │ │ ├── calc.test.js │ │ └── sum.test.js │ ├── responsive │ ├── package-lock.json │ ├── package.json │ ├── src │ │ ├── isMobile.js │ │ └── styles.css │ └── test │ │ ├── isMobile.test.js │ │ └── my-card.test.html │ ├── test-runner-coverage │ ├── package-lock.json │ ├── package.json │ ├── src │ │ └── calc.js │ └── test │ │ └── calc.test.js │ ├── typescript │ ├── package-lock.json │ ├── package.json │ ├── src │ │ ├── sum.js │ │ ├── sum.js.map │ │ └── sum.ts │ ├── test │ │ ├── sum.test.js │ │ ├── sum.test.js.map │ │ └── sum.test.ts │ └── tsconfig.json │ └── watch-and-debug │ ├── package-lock.json │ ├── package.json │ ├── src │ ├── calc.js │ └── sum.js │ └── test │ ├── calc.test.js │ └── sum.test.js ├── html-test ├── README.md ├── demo │ └── index.html ├── index.js ├── my-element.js ├── package-lock.json ├── package.json ├── src │ └── MyElement.js └── test │ └── my-element.test.html ├── import-maps ├── README.md ├── index.js ├── my-element.js ├── package-lock.json ├── package.json ├── src │ └── MyElement.js ├── test │ └── my-element.test.js └── web-test-runner.config.mjs ├── json-modules ├── README.md ├── demo │ └── index.html ├── index.js ├── my-element.js ├── package-lock.json ├── package.json ├── src │ ├── MyElement.js │ └── data.json ├── test │ └── my-element.test.js ├── web-dev-server.config.mjs └── web-test-runner.config.mjs ├── lit-element-ts-esbuild ├── demo │ └── index.html ├── index.ts ├── my-element.ts ├── package-lock.json ├── package.json ├── src │ └── MyElement.ts ├── test │ └── my-element.test.ts ├── tsconfig.json ├── web-dev-server.config.mjs └── web-test-runner.config.mjs ├── lit-element-ts-tsc ├── demo │ └── index.html ├── index.ts ├── my-element.ts ├── package-lock.json ├── package.json ├── src │ └── MyElement.ts ├── test │ └── my-element.test.ts └── tsconfig.json ├── lit-element ├── README.md ├── demo │ └── index.html ├── index.js ├── my-element.js ├── package-lock.json ├── package.json ├── src │ └── MyElement.js └── test │ └── my-element.test.js ├── mock-es-module ├── README.md ├── package-lock.json ├── package.json ├── src │ ├── postData.js │ └── postMessage.js ├── test │ ├── mocks │ │ └── postData.js │ └── postMessage.test.html └── web-test-runner.config.mjs ├── playwright ├── demo │ └── index.html ├── index.js ├── my-element.js ├── package-lock.json ├── package.json ├── src │ └── MyElement.js └── test │ └── my-element.test.js ├── preact-htm ├── demo │ └── index.html ├── package-lock.json ├── package.json ├── src │ └── App.js ├── test │ ├── app.test.js │ └── test-helpers.js └── web-test-runner.config.mjs ├── preact-jsx ├── demo │ ├── index.html │ └── index.jsx ├── package-lock.json ├── package.json ├── src │ └── App.jsx ├── test │ ├── app.test.jsx │ └── test-helpers.jsx ├── web-dev-server.config.mjs └── web-test-runner.config.mjs ├── preact-tsx ├── demo │ ├── index.html │ └── index.tsx ├── package-lock.json ├── package.json ├── src │ └── App.tsx ├── test │ ├── app.test.tsx │ └── test-helpers.tsx ├── tsconfig.json ├── web-dev-server.config.mjs └── web-test-runner.config.mjs ├── puppeteer ├── demo │ └── index.html ├── index.js ├── my-element.js ├── package-lock.json ├── package.json ├── src │ └── MyElement.js └── test │ └── my-element.test.js ├── react-htm ├── demo │ └── index.html ├── package-lock.json ├── package.json ├── src │ └── App.js ├── test │ ├── app.test.js │ └── test-helpers.js └── web-test-runner.config.mjs ├── react-jsx ├── demo │ ├── index.html │ └── index.jsx ├── package-lock.json ├── package.json ├── src │ └── App.jsx ├── test │ ├── app.test.jsx │ └── test-helpers.jsx ├── web-dev-server.config.mjs └── web-test-runner.config.mjs ├── react-tsx ├── demo │ ├── index.html │ └── index.tsx ├── package-lock.json ├── package.json ├── src │ └── App.tsx ├── test │ ├── app.test.tsx │ └── test-helpers.tsx ├── tsconfig.json ├── web-dev-server.config.mjs └── web-test-runner.config.mjs ├── renovate.json ├── saucelabs ├── demo │ └── index.html ├── index.js ├── my-element.js ├── package-lock.json ├── package.json ├── src │ └── MyElement.js ├── test │ └── my-element.test.js └── web-test-runner.config.mjs ├── snowpack-lit ├── .gitignore ├── .prettierrc ├── LICENSE ├── README.md ├── babel.config.json ├── package-lock.json ├── package.json ├── public │ ├── favicon.ico │ ├── index.css │ ├── index.html │ └── robots.txt ├── snowpack.config.js ├── src │ ├── app-root.test.ts │ ├── app-root.ts │ └── index.ts ├── tsconfig.json ├── types │ └── static.d.ts └── web-test-runner.config.js ├── snowpack-react ├── .npmignore ├── .prettierrc ├── README.md ├── package-lock.json ├── package.json ├── public │ ├── favicon.ico │ ├── index.html │ └── robots.txt ├── snowpack.config.js ├── src │ ├── App.css │ ├── App.jsx │ ├── App.test.jsx │ ├── index.css │ ├── index.jsx │ └── logo.svg └── web-test-runner.config.js ├── snowpack-svelte ├── .gitignore ├── LICENSE ├── README.md ├── package-lock.json ├── package.json ├── public │ ├── favicon.ico │ ├── index.html │ ├── logo.svg │ └── robots.txt ├── snowpack.config.js ├── src │ ├── App.svelte │ ├── App.test.js │ └── index.js └── web-test-runner.config.js ├── storybook ├── .storybook │ ├── main.js │ └── server.config.mjs ├── README.md ├── index.js ├── my-element.js ├── package-lock.json ├── package.json ├── src │ └── MyElement.js └── stories │ └── MyElement.stories.js └── visual-regression ├── README.md ├── demo └── index.html ├── index.js ├── my-element.js ├── package-lock.json ├── package.json ├── src └── MyElement.js ├── test └── my-element.test.js └── web-test-runner.config.mjs /.github/workflows/verify.yml: -------------------------------------------------------------------------------- 1 | name: Verify changes 2 | 3 | on: pull_request 4 | 5 | jobs: 6 | verify: 7 | name: Verify changes 8 | runs-on: ubuntu-latest 9 | strategy: 10 | matrix: 11 | project: 12 | [ 13 | lit-element, 14 | lit-element-ts-esbuild, 15 | lit-element-ts-tsc, 16 | html-test, 17 | preact-htm, 18 | preact-jsx, 19 | preact-tsx, 20 | puppeteer, 21 | playwright, 22 | import-maps, 23 | mock-es-module, 24 | visual-regression, 25 | saucelabs, 26 | guides/test-runner/getting-started, 27 | guides/test-runner/watch-and-debug, 28 | guides/test-runner/playwright, 29 | guides/test-runner/responsive, 30 | guides/test-runner/typescript, 31 | react-htm, 32 | react-jsx, 33 | react-tsx, 34 | snowpack-lit, 35 | snowpack-react, 36 | snowpack-svelte, 37 | ] 38 | steps: 39 | - uses: actions/checkout@v4 40 | 41 | - name: Setup Node 42 | uses: actions/setup-node@v4 43 | with: 44 | node-version: 14 45 | 46 | - uses: microsoft/playwright-github-action@v1 47 | 48 | - name: Install dependencies 49 | working-directory: ${{ matrix.project }} 50 | run: npm ci 51 | 52 | - name: Test 53 | working-directory: ${{ matrix.project }} 54 | run: npm run test 55 | env: 56 | SAUCE_ACCESS_KEY: ${{ secrets.SAUCE_ACCESS_KEY }} 57 | SAUCE_USERNAME: ${{ secrets.SAUCE_USERNAME }} 58 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## editors 2 | /.idea 3 | /.vscode 4 | 5 | ## system files 6 | .DS_Store 7 | 8 | ## npm 9 | node_modules 10 | npm-debug.log 11 | yarn-error.log 12 | /*/yarn.lock 13 | 14 | ## temp folders 15 | /.tmp/ 16 | 17 | ## testing 18 | coverage 19 | local.log 20 | 21 | ## build output 22 | dist 23 | tsconfig.tsbuildinfo 24 | /*/dist 25 | /*/tsc-out 26 | 27 | /*/screenshots -------------------------------------------------------------------------------- /guides/dev-server/getting-started/demo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | Hello world! 5 | 6 | -------------------------------------------------------------------------------- /guides/dev-server/getting-started/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@web/guides-dev-server-getting-started", 3 | "version": "0.1.0", 4 | "private": true, 5 | "license": "MIT", 6 | "scripts": { 7 | "start": "web-dev-server --open /demo/" 8 | }, 9 | "devDependencies": { 10 | "@web/dev-server": "0.4.6" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /guides/dev-server/loading-modules/demo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /guides/dev-server/loading-modules/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@web/guides-dev-server-loading-modules", 3 | "version": "0.1.0", 4 | "private": true, 5 | "license": "MIT", 6 | "scripts": { 7 | "start": "web-dev-server --open /demo/ --node-resolve" 8 | }, 9 | "devDependencies": { 10 | "@web/dev-server": "0.4.6" 11 | }, 12 | "dependencies": { 13 | "lit-html": "1.4.1" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /guides/dev-server/loading-modules/src/message.js: -------------------------------------------------------------------------------- 1 | export const message = "This is a message"; 2 | -------------------------------------------------------------------------------- /guides/dev-server/proxy-to-other-servers/api-server.mjs: -------------------------------------------------------------------------------- 1 | import http from "http"; 2 | 3 | const server = http.createServer((request, response) => { 4 | if (request.url === "/api/message") { 5 | response.writeHead(200); 6 | response.end("Hello from API"); 7 | } 8 | }); 9 | 10 | server.listen(9000); 11 | -------------------------------------------------------------------------------- /guides/dev-server/proxy-to-other-servers/demo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /guides/dev-server/proxy-to-other-servers/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@web/guides-dev-server-proxy-to-other-servers", 3 | "version": "0.1.0", 4 | "private": true, 5 | "license": "MIT", 6 | "scripts": { 7 | "start": "web-dev-server --open /demo/ --node-resolve" 8 | }, 9 | "devDependencies": { 10 | "@web/dev-server": "0.4.6", 11 | "koa-proxies": "0.12.4" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /guides/dev-server/proxy-to-other-servers/web-dev-server.config.mjs: -------------------------------------------------------------------------------- 1 | import proxy from "koa-proxies"; 2 | import "./api-server.mjs"; 3 | 4 | export default { 5 | port: 8000, 6 | middleware: [ 7 | proxy("/api/", { 8 | target: "http://localhost:9000/", 9 | }), 10 | ], 11 | }; 12 | -------------------------------------------------------------------------------- /guides/dev-server/typescript-and-jsx/demo/jsx.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /guides/dev-server/typescript-and-jsx/demo/ts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /guides/dev-server/typescript-and-jsx/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@web/guides-dev-server-typescript-and-jsx", 3 | "version": "0.1.0", 4 | "private": true, 5 | "license": "MIT", 6 | "scripts": { 7 | "start:ts": "web-dev-server --config web-dev-server.ts.mjs --open /demo/ts.html --node-resolve", 8 | "start:jsx": "web-dev-server --config web-dev-server.jsx.mjs --open /demo/jsx.html --node-resolve" 9 | }, 10 | "devDependencies": { 11 | "@web/dev-server": "0.4.6", 12 | "@web/dev-server-esbuild": "0.4.4", 13 | "preact": "10.22.0" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /guides/dev-server/typescript-and-jsx/src/app.jsx: -------------------------------------------------------------------------------- 1 | import { h, render } from 'preact'; 2 | 3 | function App() { 4 | returnHello world
5 | } 6 | 7 | render(Hello world
5 | } 6 | 7 | render(Hello world!
5 | 6 | -------------------------------------------------------------------------------- /guides/dev-server/writing-plugins/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@web/guides-dev-server-writing-plugins", 3 | "version": "0.1.0", 4 | "private": true, 5 | "license": "MIT", 6 | "scripts": { 7 | "start:inject": "web-dev-server --config web-dev-server.inject.mjs --open /demo/ --node-resolve", 8 | "start:env": "web-dev-server --config web-dev-server.env.mjs --open /demo/env.html" 9 | }, 10 | "devDependencies": { 11 | "@web/dev-server": "0.4.6" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /guides/dev-server/writing-plugins/src/logger.js: -------------------------------------------------------------------------------- 1 | import { environment } from "/environment.js"; 2 | 3 | export function logDebug(msg) { 4 | if (environment === "development") { 5 | console.log(msg); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /guides/dev-server/writing-plugins/web-dev-server.env.mjs: -------------------------------------------------------------------------------- 1 | export default { 2 | plugins: [ 3 | { 4 | name: "environment", 5 | serve(context) { 6 | if (context.path === "/environment.js") { 7 | return 'export const environment = "development";'; 8 | } 9 | }, 10 | }, 11 | ], 12 | }; 13 | -------------------------------------------------------------------------------- /guides/dev-server/writing-plugins/web-dev-server.inject.mjs: -------------------------------------------------------------------------------- 1 | export default { 2 | plugins: [ 3 | { 4 | name: "inject-html-plugin", 5 | transform(context) { 6 | if (context.path === "/demo/") { 7 | return context.body.replace( 8 | " 17 | 18 | 19 | 40 |", 9 | "
Injected by my plugin
" 10 | ); 11 | } 12 | }, 13 | }, 14 | ], 15 | }; 16 | -------------------------------------------------------------------------------- /guides/test-runner/getting-started/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@web/guides-test-runner-getting-started", 3 | "version": "0.1.0", 4 | "private": true, 5 | "license": "MIT", 6 | "scripts": { 7 | "test": "web-test-runner \"test/**/*.test.js\" --node-resolve" 8 | }, 9 | "devDependencies": { 10 | "@esm-bundle/chai": "4.3.4", 11 | "@web/test-runner": "0.16.0" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /guides/test-runner/getting-started/src/sum.js: -------------------------------------------------------------------------------- 1 | export function sum(a, b) { 2 | return a + b; 3 | } 4 | -------------------------------------------------------------------------------- /guides/test-runner/getting-started/test/sum.test.js: -------------------------------------------------------------------------------- 1 | import { expect } from "@esm-bundle/chai"; 2 | import { sum } from "../src/sum.js"; 3 | 4 | it("sums up 2 numbers", () => { 5 | expect(sum(1, 1)).to.equal(2); 6 | expect(sum(3, 12)).to.equal(15); 7 | }); 8 | -------------------------------------------------------------------------------- /guides/test-runner/playwright/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@web/guides-test-runner-playwright", 3 | "version": "0.1.0", 4 | "private": true, 5 | "license": "MIT", 6 | "scripts": { 7 | "test": "web-test-runner \"test/**/*.test.js\" --node-resolve --playwright --browsers chromium firefox webkit" 8 | }, 9 | "devDependencies": { 10 | "@esm-bundle/chai": "4.3.4", 11 | "@web/test-runner": "0.16.0", 12 | "@web/test-runner-playwright": "0.10.0" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /guides/test-runner/playwright/src/calc.js: -------------------------------------------------------------------------------- 1 | import { sum } from './sum.js'; 2 | 3 | export function calc(inputString) { 4 | const numbers = inputString.split('+').map(number => parseInt(number)); 5 | return sum(...numbers); 6 | } 7 | -------------------------------------------------------------------------------- /guides/test-runner/playwright/src/sum.js: -------------------------------------------------------------------------------- 1 | export function sum(...numbers) { 2 | let sum = 0; 3 | for (const number of numbers) { 4 | sum += number; 5 | } 6 | return sum; 7 | } 8 | -------------------------------------------------------------------------------- /guides/test-runner/playwright/test/calc.test.js: -------------------------------------------------------------------------------- 1 | import { expect } from "@esm-bundle/chai"; 2 | import { calc } from '../src/calc.js'; 3 | 4 | it('calculates sums', () => { 5 | expect(calc('1 + 1 + 1')).to.equal(3); 6 | expect(calc('2 + 6 + 12')).to.equal(20); 7 | }); 8 | -------------------------------------------------------------------------------- /guides/test-runner/playwright/test/sum.test.js: -------------------------------------------------------------------------------- 1 | import { expect } from "@esm-bundle/chai"; 2 | import { sum } from '../src/sum.js'; 3 | 4 | it('sums up 2 numbers', () => { 5 | expect(sum(1, 1)).to.equal(2); 6 | expect(sum(3, 12)).to.equal(15); 7 | }); 8 | 9 | it('sums up 3 numbers', () => { 10 | expect(sum(1, 1, 1)).to.equal(3); 11 | expect(sum(3, 12, 5)).to.equal(20); 12 | }); 13 | -------------------------------------------------------------------------------- /guides/test-runner/responsive/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@web/guides-test-runner-responsive", 3 | "version": "0.1.0", 4 | "private": true, 5 | "license": "MIT", 6 | "scripts": { 7 | "test": "web-test-runner \"test/**/*.test.{html,js}\" --node-resolve", 8 | "test:watch": "web-test-runner \"test/**/*.test.{html,js}\" --node-resolve --watch" 9 | }, 10 | "devDependencies": { 11 | "@esm-bundle/chai": "4.3.4", 12 | "@web/test-runner-mocha": "0.9.0", 13 | "@web/test-runner": "0.16.0", 14 | "@web/test-runner-commands": "0.9.0" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /guides/test-runner/responsive/src/isMobile.js: -------------------------------------------------------------------------------- 1 | export function isMobile() { 2 | return !!window.matchMedia('(max-width: 1024px)').matches; 3 | } 4 | -------------------------------------------------------------------------------- /guides/test-runner/responsive/src/styles.css: -------------------------------------------------------------------------------- 1 | .card { 2 | background: rgb(0, 255, 0); 3 | } 4 | 5 | @media screen and (min-width: 1024px) { 6 | .card { 7 | background: rgb(255, 0, 0); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /guides/test-runner/responsive/test/isMobile.test.js: -------------------------------------------------------------------------------- 1 | import { expect } from "@esm-bundle/chai"; 2 | import { setViewport } from '@web/test-runner-commands'; 3 | import { isMobile } from '../src/isMobile'; 4 | 5 | describe('isMobile', () => { 6 | it('returns true if width < 1024px', async () => { 7 | await setViewport({ width: 360, height: 640 }); 8 | expect(isMobile()).to.be.true; 9 | }); 10 | 11 | it('returns false if width > 1024px', async () => { 12 | await setViewport({ width: 1200, height: 640 }); 13 | expect(isMobile()).to.be.false; 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /guides/test-runner/responsive/test/my-card.test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 15 | 16 |
41 |