### Proxy API Requests and Start Other Servers with serverStart Hook Source: https://modern-web.dev/docs/dev-server/writing-plugins/hooks This serverStart hook example shows how to set up API proxying using koa-proxies and start another server. The dev server will wait for the other server to start because the serverStart hook is awaited. ```javascript import proxy from 'koa-proxies'; export default { plugins: [ { name: 'my-plugin', async serverStart({ app }) { // set up a proxy for certain requests app.use( proxy('/api', { target: 'http://localhost:9001', }), ); // boot up the other server because it is awaited the dev server will also wait for it await startOtherServer({ port: 9001 }); }, }, ], }; ``` -------------------------------- ### Install Recommended Storybook Addons Source: https://modern-web.dev/docs/storybook-builder/migration-to-storybook-7 Install essential Storybook 7 addons like `@storybook/addon-essentials` and `@storybook/addon-links`. These provide common UI components and functionalities for your Storybook environment. ```bash npm install @storybook/addon-essentials@7 @storybook/addon-links@7 --save-dev ``` -------------------------------- ### Minimal Test Framework Example (JavaScript) Source: https://modern-web.dev/docs/test-runner/test-frameworks/write-your-own This JavaScript code snippet demonstrates a minimal test framework setup for a web test runner. It shows how to initiate a test session, retrieve test configuration, load test files as ES modules, and handle test execution and results reporting. It relies on the '@web/test-runner-core/browser/session.js' module for session management. ```javascript import { getConfig, sessionStarted, sessionFinished, sessionFailed, } from '@web/test-runner-core/browser/session.js'; (async () => { // notify the test runner that we're alive sessionStarted(); // fetch the config for this test run, this will tell you which file we're testing const { testFile, watch, debug, testFrameworkConfig } = await getConfig(); const failedImports = []; // load the test file as an es module await import(new URL(testFile, document.baseURI).href).catch(error => { failedImports.push({ file: testFile, error: { message: error.message, stack: error.stack } }); }); try { // run the actual tests, this is what you need to implement const testResults = await runTests(); // notify tests run finished sessionFinished({ passed: failedImports.length === 0 && testResults.passed, failedImports, testResults, }); } catch (error) { // notify an error occurred sessionFailed(error); return; } })(); ``` -------------------------------- ### Serve Environment Variables as Virtual Module (JavaScript) Source: https://modern-web.dev/docs/dev-server/writing-plugins/examples This example demonstrates how to create a virtual module to serve environment variables. It reads the version from package.json and makes it available in the browser. This approach requires a plugin to serve the virtual module content. ```javascript import fs from 'fs'; import path from 'path'; const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf-8')); export default { plugins: [ { name: 'env-vars', serve(context) { if (context.path === '/environment.js') { return `export default { version: "${packageJson.version}" }`; } }, }, ], }; ``` ```javascript import { version } from '../environment.js'; console.log(`The current version is: ${version}`); ``` -------------------------------- ### Run Dev Server with CLI Flags Source: https://modern-web.dev/docs/dev-server/cli-and-configuration Examples of how to start the web dev server using various CLI flags to control its behavior, such as opening the browser, enabling module resolution, and watching for file changes. ```bash web-dev-server --open web-dev-server --node-resolve web-dev-server --node-resolve --watch web-dev-server --node-resolve --watch --app-index demo/index.html web-dev-server --node-resolve --watch --app-index demo/index.html --esbuild-target auto ``` ```bash wds --node-resolve --watch --app-index demo/index.html --esbuild-target auto ``` -------------------------------- ### Install and Use Puppeteer with @web/test-runner Source: https://modern-web.dev/docs/test-runner/browser-launchers/puppeteer Installs the Puppeteer launcher for @web/test-runner and demonstrates basic usage with command-line flags to run tests using Puppeteer. ```bash # add the package npm i --save-dev @web/test-runner-puppeteer # add the flag wtr test/**/*.test.js --node-resolve --puppeteer ``` -------------------------------- ### Add Custom Polyfills with Test and Initialization Source: https://modern-web.dev/docs/building/polyfills-loader This example shows how to add a custom polyfill. It includes a unique name, path, a test to determine when to load it, and optional settings for minification and initialization. ```javascript const config = { polyfills: { hash: true, fetch: true, custom: [ { // the name, must be unique name: 'my-feature-polyfill', // path to the polyfill fle path: require.resolve('my-feature-polyfill'), // a test that determines when this polyfill should be loaded // often this is done by checking whether some property of a // feature exists in the window test: "!('myFeature' in window)", // optional advanced features: // if your polyfill is not yet minified, it can be minified by // the polyfills loaded if you set it to true minify: true, // whether your polyfill should be loaded as an es module module: false, // some polyfills need to be explicitly initialized // this can be done with the initializer initializer: 'window.myFeaturePolyfills.initialize()', }, ], }, }; ``` -------------------------------- ### Serve Mocked Module with Web Server (JavaScript) Source: https://modern-web.dev/docs/dev-server/writing-plugins/examples This example illustrates how to serve a mocked or stubbed version of a module from the web server. This is necessary because ES modules are immutable at runtime in the browser. This affects all tests when used in a test runner context. ```javascript export default { plugins: [ { name: 'stub-package', serve(context) { if (context.path === '/node_modules/some-package/index.js') { return " export default doFoo() { console.log(\"stubbing foo\"); } export default doBar() { console.log(\"stubbing bar\"); }"; } }, }, ], }; ``` -------------------------------- ### Install @web/rollup-plugin-copy Source: https://modern-web.dev/docs/building/rollup-plugin-copy Installs the necessary Rollup plugin for copying assets. This command is executed in the terminal. ```bash npm install --save-dev @web/rollup-plugin-copy ``` -------------------------------- ### Start Dev Server Programmatically (Node.js) Source: https://modern-web.dev/docs/dev-server/node-api Starts the dev server with default options using the `startDevServer` function. It returns a dev server instance that can be used programmatically. This is equivalent to running the `web-dev-server` or `wds` command. ```javascript import { startDevServer } from '@web/dev-server'; async function main() { const server = await startDevServer(); } main(); ``` -------------------------------- ### Install Web Components Storybook Framework Source: https://modern-web.dev/docs/storybook-builder/frameworks Installs the Storybook framework specifically designed for Web Components and the `@web/storybook-builder`. This is a prerequisite for configuring Storybook for Web Component projects. ```bash npm install @web/storybook-framework-web-components --save-dev ``` -------------------------------- ### Install @web/test-runner-commands Source: https://modern-web.dev/docs/test-runner/commands Installs the @web/test-runner-commands library as a development dependency using npm. ```bash npm i --save-dev @web/test-runner-commands ``` -------------------------------- ### Start Web Dev Server (Basic) Source: https://modern-web.dev/docs/dev-server/overview Starts the Web Dev Server with basic configurations, including resolving node modules and automatically opening the default browser. This is a fundamental command for running a development server. ```bash web-dev-server --node-resolve --open ``` ```bash wds --node-resolve --open ``` -------------------------------- ### Install Old Builder and Renderer for Upgrade Source: https://modern-web.dev/docs/storybook-builder/migration-to-storybook-7 Before running the Storybook upgrade CLI, install the old version of `@storybook/builder-vite` and the Storybook 6 renderer for your specific technology (e.g., Web Components). This ensures compatibility with the upgrade script. ```bash npm install @storybook/builder-vite@0.4 @storybook/web-components@6 --save-dev ``` -------------------------------- ### Start Dev Server with Custom Configuration (Node.js) Source: https://modern-web.dev/docs/dev-server/node-api Starts the dev server with a custom configuration object, overriding default settings and ignoring CLI arguments or file configurations. This allows for programmatic control over options like `rootDir`, `port`, and `watch`. ```javascript import { startDevServer } from '@web/dev-server'; async function main() { const server = await startDevServer({ config: { rootDir: process.cwd(), port: 1234, watch: true, }, readCliArgs: false, readFileConfig: false, }); } main(); ``` -------------------------------- ### Plugin Configuration Example Source: https://modern-web.dev/docs/dev-server/writing-plugins/overview This example demonstrates how to configure plugins in your `web-dev-server.config.mjs` or `web-test-runner.config.mjs` file, including using an external plugin and defining an inline plugin. ```APIDOC ## POST /websites/modern-web_dev/plugins ### Description This section details how to configure and use plugins within the modern web development server. ### Method POST ### Endpoint /websites/modern-web_dev/plugins ### Parameters #### Query Parameters - **config_file** (string) - Optional - The path to the configuration file (e.g., `web-dev-server.config.mjs`). #### Request Body - **plugins** (array) - Required - An array of plugin configurations. Each plugin can be an imported module or an inline object. - **name** (string) - Required - The name of the plugin. - **options** (object) - Optional - Configuration options for the plugin. - **transform** (function) - Optional - A function to transform files. - **resolveImport** (function) - Optional - A function to resolve module imports. - **serve** (function) - Optional - A function to serve files. - **resolveMimeType** (function) - Optional - A function to resolve MIME types. ### Request Example ```json { "plugins": [ { "name": "awesome-plugin", "options": { "someOption": "someProperty" } }, { "name": "my-plugin", "transform": "(context) => { if (context.response.is('html')) { return { body: context.body.replace(//, '') }; } }" } ] } ``` ### Response #### Success Response (200) - **message** (string) - A confirmation message indicating that the plugins have been configured successfully. #### Response Example ```json { "message": "Plugins configured successfully." } ``` ``` -------------------------------- ### Install Web Dev Server (npm) Source: https://modern-web.dev/docs/dev-server/overview Installs the Web Dev Server package as a development dependency using npm. This command should be run in your project's root directory. ```bash npm i --save-dev @web/dev-server ``` -------------------------------- ### Install Framework for @web/storybook-builder Source: https://modern-web.dev/docs/storybook-builder/overview Installs a framework-specific package, such as for Web Components, to integrate with @web/storybook-builder. Ensure you install the correct framework package for your project. ```bash npm install @web/storybook-framework-web-components --save-dev ``` -------------------------------- ### Install @web/dev-server-legacy Plugin Source: https://modern-web.dev/docs/dev-server/plugins/legacy Installs the legacy plugin for the web dev server as a development dependency using npm. ```bash npm i --save-dev @web/dev-server-legacy ``` -------------------------------- ### Assertion Example with @esm-bundle/chai Source: https://modern-web.dev/docs/test-runner/writing-tests/helper-libraries Demonstrates how to use the Chai assertion library, bundled as an ES module, for making assertions in tests. It requires the @esm-bundle/chai package. ```javascript import { expect } from '@esm-bundle/chai'; expect(undefined).to.not.be.a('function'); ``` -------------------------------- ### Import Modules in Browser via Web Sockets (JavaScript) Source: https://modern-web.dev/docs/dev-server/writing-plugins/web-sockets This example shows how to use `webSockets.sendImport` to instruct the browser to import a specified module path. The plugin can either serve a real file or a virtual file, and the imported module must have a default export. The `serverStart` hook is used to initiate the import after a delay. ```javascript function myPlugin() { let webSockets; return { name: 'my-plugin', injectWebSocket: true, serverStart(options) { ({ webSockets } = options); setTimeout(() => { // this will import /foo.js in the browser webSockets.sendImport('/foo.js'); }, 1000); }, serve(context) { // you can serve a virtual module to be imported if (context.path === '/foo.js') { return 'export default () => console.log("/foo.js");'; } }, }; } ``` -------------------------------- ### Start Web Dev Server (ESBuild Target Auto) Source: https://modern-web.dev/docs/dev-server/overview Starts the Web Dev Server and transforms JavaScript code to a compatible syntax based on the user agent, leveraging esbuild for efficient transpilation. The 'auto' target automatically detects the browser's capabilities. ```bash web-dev-server --node-resolve --open --esbuild-target auto ``` ```bash wds --node-resolve --open --esbuild-target auto ``` -------------------------------- ### Handle Incoming Messages from Browser via Web Sockets (JavaScript) Source: https://modern-web.dev/docs/dev-server/writing-plugins/web-sockets This example shows how to listen for and respond to messages sent from the browser using the `webSockets.on('message', ...)` event listener within the `serverStart` hook. It logs received messages and sends a response back to the specific web socket that initiated the communication. ```javascript function myPlugin() { return { name: 'my-plugin', injectWebSocket: true, serverStart({ webSockets }) { webSockets.on('message', ({ webSocket, data }) => { console.log('received message', data); webSocket.send('message response'); }); }, }; } ``` -------------------------------- ### Install @web/storybook-builder Source: https://modern-web.dev/docs/storybook-builder/overview Installs the core @web/storybook-builder package as a development dependency using npm. This is the first step in setting up Storybook with this builder. ```bash npm install @web/storybook-builder --save-dev ``` -------------------------------- ### Example: Referencing an SVG Asset Source: https://modern-web.dev/docs/building/rollup-plugin-import-meta-assets Shows an example of referencing an SVG asset using `new URL` and `import.meta.url` in `entrypoint.js`. The output directory structure and the transformed `bundle.js` content are also presented. ```javascript const imageUrl = new URL('./one/two/the-image.svg', import.meta.url).href; console.log(imageUrl); ``` ```javascript const imageUrl = new URL(new URL('asset/the-image.svg', import.meta.url).href, import.meta.url) .href; console.log(imageUrl); ``` -------------------------------- ### Polyfills Loader Configuration Example (JavaScript) Source: https://modern-web.dev/docs/building/polyfills-loader This JavaScript object illustrates a typical configuration for the polyfills loader. It defines settings for modern and legacy browser builds, including the files to load and conditions for legacy loading. It also specifies which polyfills to include, whether to hash them, and options for minification and external script loading. ```javascript const config = { modern: { files: [{ type: 'module', path: 'app.js' }], }, legacy: [ { test: "!('noModule' in HTMLScriptElement.prototype)", files: [{ type: 'systemjs', path: 'app.js' }], }, ], polyfills: { hash: true, coreJs: true, fetch: true, abortController: true, regeneratorRuntime: true, dynamicImport: true, webcomponents: true, intersectionObserver: true, resizeObserver: true, }, minify: true, externalLoaderScript: false, }; ``` -------------------------------- ### Install Sauce Labs Browser Launcher Source: https://modern-web.dev/docs/test-runner/browser-launchers/saucelabs Installs the necessary package for integrating Sauce Labs browser launchers with the web test runner. This is the first step to enable remote browser testing. ```bash npm i --save-dev @web/test-runner-saucelabs ``` -------------------------------- ### Customize HTML Environment per Test Group Source: https://modern-web.dev/docs/test-runner/cli-and-configuration Apply unique HTML environments to different test groups, enabling specific polyfills or setup scripts for each group. This example shows injecting 'polyfills-a.js' for one group and 'polyfills-b.js' for another. ```javascript import { playwrightLauncher } from '@web/test-runner-playwright'; export default { files: 'test/**/*.test.js', browsers: [ playwrightLauncher({ product: 'chromium' }), playwrightLauncher({ product: 'webkit' }), playwrightLauncher({ product: 'firefox' }), ], groups: [ { name: 'polyfills-a', testRunnerHtml: testFramework => ` `, }, { name: 'polyfills-b', testRunnerHtml: testFramework => ` `, }, ], }; ``` -------------------------------- ### Configure Dev Server with JavaScript (CommonJS) Source: https://modern-web.dev/docs/dev-server/cli-and-configuration Example of a web dev server configuration file written in JavaScript using CommonJS module syntax. This configuration mirrors the ES module example, setting options for opening the browser, resolving modules, and specifying the application index. ```javascript module.exports = { open: true, nodeResolve: true, appIndex: 'demo/index.html' // in a monorepo you need to set the root dir to resolve modules rootDir: '../../', }; ``` -------------------------------- ### Register Storybook Addons in Main Config Source: https://modern-web.dev/docs/storybook-builder/migration-to-storybook-7 Register the newly installed addons in your Storybook main configuration file (`.storybook/main.js`). This makes them available for use in your Storybook instance. ```javascript // .storybook/main.js /** @type { import('@web/storybook-framework-web-components').StorybookConfig } */ const config = { ... addons: [ '@storybook/addon-essentials', '@storybook/addon-links', ... ], ... }; export default config; ``` -------------------------------- ### Install Esbuild Plugin for Web Dev Server Source: https://modern-web.dev/docs/dev-server/plugins/esbuild Installs the necessary esbuild plugin package for Web Dev Server using npm. This is the first step to enable esbuild transformations. ```bash npm i --save-dev @web/dev-server-esbuild ``` -------------------------------- ### Install Web Test Runner (npm) Source: https://modern-web.dev/docs/test-runner/overview Installs the Web Test Runner package as a development dependency using npm. This is the first step to integrating the test runner into your project. ```bash npm i --save-dev @web/test-runner ``` -------------------------------- ### Example: Mocking a Module with Import Maps in an HTML Test Source: https://modern-web.dev/docs/test-runner/writing-tests/mocking Provides a complete HTML test file example using Mocha and Chai, demonstrating how to use an inline import map to mock a specific module (`./postData.js`) for testing the `sendMessage` function without side effects. ```html ``` -------------------------------- ### Install @web/rollup-plugin-import-meta-assets Source: https://modern-web.dev/docs/building/rollup-plugin-import-meta-assets Provides the npm command to install the '@web/rollup-plugin-import-meta-assets' package as a development dependency. ```bash npm install @web/rollup-plugin-import-meta-assets --save-dev ``` -------------------------------- ### Install @web/rollup-plugin-html Source: https://modern-web.dev/docs/building/rollup-plugin-html Installs the @web/rollup-plugin-html package as a development dependency using npm. ```bash npm install --save-dev @web/rollup-plugin-html ``` -------------------------------- ### Import Code via Data URL using Web Sockets (JavaScript) Source: https://modern-web.dev/docs/dev-server/writing-plugins/web-sockets This example illustrates a concise way to execute simple JavaScript code in the browser by sending it as a data URL via `webSockets.sendImport`. This method is particularly useful for straightforward actions like reloading the browser page. ```javascript function myPlugin() { let webSockets; return { name: 'my-plugin', injectWebSocket: true, serverStart(options) { ({ webSockets } = options); setTimeout(() => { // this will reload the browser webSockets.sendImport('data:text/javascript,window.location.reload()'); }, 1000); }, }; } ``` -------------------------------- ### Emulate Mobile Browser with Puppeteer Source: https://modern-web.dev/docs/test-runner/browser-launchers/puppeteer Provides an example of how to emulate a mobile browser, specifically the 'Pixel 2' device, using Puppeteer's emulation capabilities within the @web/test-runner configuration. ```javascript import { puppeteerLauncher } from '@web/test-runner-puppeteer'; import { KnownDevices } from 'puppeteer'; export default { browsers: [ puppeteerLauncher({ async createPage({ context }) { const page = await context.newPage(); page.emulate(KnownDevices['Pixel 2']); return page; }, }), ], }; ``` -------------------------------- ### Install Import Maps Plugin Source: https://modern-web.dev/docs/dev-server/plugins/import-maps Command to install the @web/dev-server-import-maps package as a development dependency. ```bash npm i --save-dev @web/dev-server-import-maps ``` -------------------------------- ### Configure Test Reporters with JavaScript - Modern Web Guides Source: https://modern-web.dev/docs/test-runner/reporters/overview Demonstrates how to configure custom test reporters using the 'reporters' option in a JavaScript configuration file for Modern Web Guides. It shows importing and using the default reporter for progress and a custom reporter for results. Dependencies include '@web/test-runner' and a custom 'my-reporter'. ```javascript // import the browser launcher you want to use import { defaultReporter } from '@web/test-runner'; import { myReporter } from 'my-reporter'; export default { reporters: [ // use the default reporter only for reporting test progress defaultReporter({ reportTestResults: false, reportTestProgress: true }), // use another reporter to report test results myReporter(), ], }; ``` -------------------------------- ### Run Storybook Upgrade CLI Source: https://modern-web.dev/docs/storybook-builder/migration-to-storybook-7 Execute the Storybook 7 upgrade script using npx. This command initiates the automated upgrade process, which will guide you through the necessary changes. ```bash npx storybook@7 upgrade ``` -------------------------------- ### HTML Preload Links for Application Scripts Source: https://modern-web.dev/docs/building/polyfills-loader This HTML snippet shows how to use preload links to optimize the loading of application scripts, particularly the modern build. It includes a standard 'preload' link and a 'preload' link with the 'crossorigin' attribute set to 'anonymous', which is necessary for module scripts to ensure they are fetched correctly from the start. ```html ``` -------------------------------- ### Install and Use Playwright Browser Launcher Source: https://modern-web.dev/docs/test-runner/browser-launchers/overview This snippet demonstrates installing the Playwright browser launcher and activating it via CLI flags. Playwright supports testing across Chromium, Firefox, and WebKit. ```bash # add the package npm i --save-dev @web/test-runner-playwright # add the flag wtr test/**/*.test.js --node-resolve --playwright --browsers chromium firefox webkit ``` -------------------------------- ### Start Web Dev Server (Watch Mode) Source: https://modern-web.dev/docs/dev-server/overview Starts the Web Dev Server in watch mode, which automatically reloads the browser when file changes are detected. This enhances the development workflow by providing instant feedback. ```bash web-dev-server --node-resolve --watch --open ``` ```bash wds --node-resolve --watch --open ``` -------------------------------- ### Install and Use Puppeteer Browser Launcher Source: https://modern-web.dev/docs/test-runner/browser-launchers/overview This snippet shows how to install the Puppeteer browser launcher package and enable it using a CLI flag. Puppeteer downloads a local Chromium instance for testing. ```bash # add the package npm i --save-dev @web/test-runner-puppeteer # add the flag wtr test/**/*.test.js --node-resolve --puppeteer ``` -------------------------------- ### Import JSON Files as JS Modules (JavaScript) Source: https://modern-web.dev/docs/dev-server/writing-plugins/examples This example shows how to import JSON files directly into your JavaScript code using @rollup/plugin-json. It requires installing the plugin and configuring the dev server to serve JSON files as JavaScript modules. ```javascript import rollupJson from '@rollup/plugin-json'; import { fromRollup } from '@web/dev-server-rollup'; const json = fromRollup(rollupJson); export default { // tell the server to serve json files as js mimeTypes: { '**/*.json': 'js', }, plugins: [json({})], }; ``` -------------------------------- ### Import CSS with rollup-plugin-postcss Source: https://modern-web.dev/docs/dev-server/writing-plugins/examples This snippet demonstrates how to import CSS files using the `rollup-plugin-postcss` plugin. It configures the web dev server to serve CSS files as JavaScript and enables PostCSS processing with CSS modules. Ensure `rollup-plugin-postcss` is installed. ```javascript /* eslint-disable */ import rollupPostcss from 'rollup-plugin-postcss'; import { fromRollup } from '@web/dev-server-rollup'; const postcss = fromRollup(rollupPostcss); export default { // in a monorepo you need to adjust the rootdir of the web server // postcss injects a module which needs to be reachable from the browser // rootDir: '../..', // tell the server to serve css files as js mimeTypes: { '**/*.css': 'js', }, plugins: [postcss({ include: ['src/**/*.css'], modules: true })], }; ``` -------------------------------- ### JavaScript Custom Reporter Example Source: https://modern-web.dev/docs/test-runner/reporters/write-your-own This JavaScript function demonstrates how to create a custom reporter for a test runner. It includes optional configurations for reporting results and progress, and defines hooks for various stages of the test lifecycle, such as starting, stopping, and reporting individual test file results. ```javascript export function myReporter({ reportResults = true, reportProgress = false } = {}) { return { /** * Called once when the test runner starts. */ start({ config, sessions, testFiles, browserNames, startTime }) {}, /** * Called once when the test runner stops. This can be used to write a test * report to disk for regular test runs. */ stop({ sessions, testCoverage, focusedTestFile }) {}, /** * Called when a test run starts. Each file change in watch mode * triggers a test run. * * @param testRun the test run */ onTestRunStarted({ testRun }) {}, /** * Called when a test run is finished. Each file change in watch mode * triggers a test run. This can be used to report the end of a test run, * or to write a test report to disk in watch mode for each test run. * * @param testRun the test run */ onTestRunFinished({ testRun, sessions, testCoverage, focusedTestFile }) {}, /** * Called when results for a test file can be reported. This is called * when all browsers for a test file are finished, or when switching between * menus in watch mode. * * If your test results are calculated async, you should return a promise from * this function and use the logger to log test results. The test runner will * guard against race conditions when re-running tests in watch mode while reporting. * * @param logger the logger to use for logging tests * @param testFile the test file to report for * @param sessionsForTestFile the sessions for this test file. each browser is a * different session */ async reportTestFileResults({ logger, sessionsForTestFile, testFile }) { if (!reportResults) { return; } // test report generated async const testReport = await generateTestReport(testFile, sessionsForTestFile); logger.log(`Results for ${testFile}`); logger.group(); logger.log(testReport); logger.groupEnd(); }, /** * Called when test progress should be rendered to the terminal. This is called * any time there is a change in the test runner to display the latest status. * * This function should return the test report as a string. Previous results from this * function are overwritten each time it is called, they are rendered "dynamically" * to the terminal so that the progress bar is live updating. */ getTestProgress({ config, sessions, testFiles, startTime, testRun, focusedTestFile, testCoverage, }) { if (!reportProgress) { return; } return `Current progress: 21%`; }, }; } ``` -------------------------------- ### Initialize Plugins and Watch Files with serverStart Hook Source: https://modern-web.dev/docs/dev-server/writing-plugins/hooks The serverStart hook is used to initialize plugins and set up file watching. It receives server configuration, Koa app, HTTP server, and a file watcher instance. This example demonstrates accessing rootDir, registering Koa middleware, and adding single and multiple files for the file watcher. ```javascript import _glob from 'glob'; import { promisify } from 'util'; const glob = promisify(_glob); function myFancyPlugin() { let rootDir; return { name: 'my-plugin', serverStart({ config, app, server, fileWatcher }) { // take the rootDir to access it later rootDir = config.rootDir; // register a koa middleware directly app.use((context, next) => { console.log(context.path); return next(); }); // register a single file to be watched fileWatcher.add('/README.md'); // register multiple files to be watched const files = await glob('{elements}/**/*.{ts,css,html}', { cwd: process.cwd() }); for (const file of files) { fileWatcher.add(file); } }, }; } export default { plugins: [myFancyPlugin()], }; ``` -------------------------------- ### Install @web/dev-server-hmr Plugin Source: https://modern-web.dev/docs/dev-server/plugins/hmr Installs the HMR plugin package using npm. This is the first step to enable hot module replacement in your development server. ```bash npm i --save-dev @web/dev-server-hmr ``` -------------------------------- ### Install Browserstack Launcher for Web Test Runner Source: https://modern-web.dev/docs/test-runner/browser-launchers/browserstack Installs the necessary package for integrating Browserstack with the web test runner. This is a prerequisite for configuring remote browser testing. ```bash npm i --save-dev @web/test-runner-browserstack ``` -------------------------------- ### Enable Range Requests with Koa-Range Source: https://modern-web.dev/docs/dev-server/middleware Add support for range requests, essential for seeking in audio and video files, by integrating the `koa-range` middleware. Install the package using `npm install --save-dev koa-range`. ```javascript import range from 'koa-range'; export default { ... middleware: [ range ] }; ``` -------------------------------- ### Start Web Dev Server (SPA Routing) Source: https://modern-web.dev/docs/dev-server/overview Configures the Web Dev Server to use the History API fallback for Single Page Application (SPA) routing. This command specifies an index HTML file to handle routing for SPAs. ```bash web-dev-server --node-resolve --app-index demo/index.html --open ``` ```bash wds --node-resolve --app-index demo/index.html --open ``` -------------------------------- ### Use Babel Plugins with Rollup (JavaScript) Source: https://modern-web.dev/docs/dev-server/writing-plugins/examples This example demonstrates integrating Babel plugins into your build process using @rollup/plugin-babel. Note that the dev server and test runner already include esbuild for JavaScript compilation, so Babel is typically not needed for browser compatibility. ```javascript import rollupBabel from '@rollup/plugin-babel'; import { fromRollup } from '@web/dev-server-rollup'; const babel = fromRollup(rollupBabel); export default { plugins: [babel({ include: ['src/**/*.js'], plugins: ['babel-plugin-foo'] })], }; ``` -------------------------------- ### Import CSS with rollup-plugin-lit-css Source: https://modern-web.dev/docs/dev-server/writing-plugins/examples This example shows how to import CSS files as JavaScript modules that export tagged template literals using `rollup-plugin-lit-css`. The web dev server is configured to serve these CSS files as JavaScript. This method is useful for integrating CSS directly into Lit components. ```javascript /* eslint-disable */ import rollupLitcss from 'rollup-plugin-lit-css'; import { fromRollup } from '@web/dev-server-rollup'; const litcss = fromRollup(rollupLitcss); export default { // tell the server to serve css files as js mimeTypes: { '**/*.css': 'js', }, plugins: [litcss({ include: ['src/**/*.css'] })], }; ``` -------------------------------- ### Copy All SVGs using Rollup Plugin (JavaScript) Source: https://modern-web.dev/docs/building/rollup-plugin-copy An example of using the copy plugin to select all SVG files within the project directory and its subdirectories. ```javascript copy({ patterns: '**/*.svg' }); ``` -------------------------------- ### Import Sinon ES Module for Testing Source: https://modern-web.dev/docs/test-runner/writing-tests/mocking Demonstrates how to import Sinon.js functions like stub, spy, and useFakeTimers for use in ES module-based test environments. This is the standard way to begin using Sinon's mocking capabilities. ```javascript import { stub, spy, useFakeTimers } from 'sinon'; ``` -------------------------------- ### Advanced @web/dev-server-legacy Configuration Source: https://modern-web.dev/docs/dev-server/plugins/legacy Demonstrates advanced configuration for the legacy plugin, allowing fine-grained control over individual polyfills and the addition of custom polyfills. This enables tailored support for specific features and browser compatibility needs. ```javascript import { legacyPlugin } from '@web/dev-server-legacy'; export default { plugins: [ // make sure this plugin is always last legacyPlugin({ // these are the default values coreJs: true, regeneratorRuntime: 'always', fetch: true, abortController: true, webcomponents: true, intersectionObserver: false, resizeObserver: false, // you can also inject custom polyfills: custom: [ { // the name, must be unique name: 'my-feature-polyfill', // path to the polyfill file path: require.resolve('my-feature-polyfill'), // a test that determines when this polyfill should be loaded // often this is done by checking whether some property of a // feature exists in the window test: "!('myFeature' in window)", // whether your polyfill should be loaded as an es module module: false, // some polyfills need to be explicitly initialized // this can be done with the initializer initializer: 'window.myFeaturePolyfills.initialize()', }, ], }), ], }; ``` -------------------------------- ### Emulate Mobile Browser with Chrome Launcher Source: https://modern-web.dev/docs/test-runner/browser-launchers/chrome Provides an example of how to emulate a mobile browser, specifically the 'Pixel 2' device, using the chromeLauncher and puppeteer's KnownDevices in @web/test-runner. ```javascript import { chromeLauncher } from '@web/test-runner-chrome'; import { KnownDevices } from 'puppeteer'; export default { browsers: [ chromeLauncher({ async createPage({ context }) { const page = await context.newPage(); page.emulate(KnownDevices['Pixel 2']); return page; }, }), ], }; ``` -------------------------------- ### Configure npm Scripts for Web Dev Server Source: https://modern-web.dev/docs/dev-server/overview Adds npm scripts to your package.json file to easily start the Web Dev Server with common configurations. These scripts enable features like node module resolution, opening the browser automatically, and watching for file changes. ```json "scripts": { "start": "web-dev-server --node-resolve --open --watch" } ``` ```json "scripts": { "start": "wds --node-resolve --open --watch" } ``` -------------------------------- ### Shady CSS Scoped Element for IE11 CSS Variables Source: https://modern-web.dev/docs/building/polyfills-loader This example demonstrates how to use the `` tag to define CSS variables outside of a web component in IE11. It requires both `webcomponents` and `shadyCssCustomStyle` polyfills. ```html ``` ```javascript const config = { polyfills: { webcomponents: true, shadyCssCustomStyle: true, }, }; ``` -------------------------------- ### Copy SVGs from a Specific Root Directory (JavaScript) Source: https://modern-web.dev/docs/building/rollup-plugin-copy This example shows how to configure the copy plugin to only search for SVG files within a specified subdirectory ('./sub') and resolve paths relative to that directory. ```javascript copy({ patterns: '**/*.svg', rootDir: './sub' }); ``` -------------------------------- ### Customize Browser Context and Page Creation in Playwright Launcher Source: https://modern-web.dev/docs/test-runner/browser-launchers/playwright Provides examples of customizing the browser context and page creation functions within the Playwright launcher for @web/test-runner, allowing fine-grained control over the testing environment. ```javascript import { playwrightLauncher } from '@web/test-runner-playwright'; export default { browsers: [ playwrightLauncher({ createBrowserContext: ({ browser, config }) => browser.newContext(), createPage: ({ context, config }) => context.newPage(), }), ], }; ``` -------------------------------- ### Configure Dev Server with JavaScript (ES Module) Source: https://modern-web.dev/docs/dev-server/cli-and-configuration Example of a web dev server configuration file written in JavaScript using ES module syntax. This configuration sets options like opening the browser, resolving Node.js modules, and specifying the application index file. ```javascript export default { open: true, nodeResolve: true, appIndex: 'demo/index.html' // in a monorepo you need to set the root dir to resolve modules rootDir: '../../', }; ``` -------------------------------- ### Rewrite Request URLs with Custom Middleware Source: https://modern-web.dev/docs/dev-server/middleware Implement custom middleware to rewrite incoming request URLs. This example demonstrates serving `index.html` from a different path, which is useful for aliasing modules or adjusting file locations. ```javascript export default { middleware: [ function rewriteIndex(context, next) { if (context.url === '/' || context.url === '/index.html') { context.url = '/src/index.html'; } return next(); }, ], }; ``` -------------------------------- ### Shorthand Command for Running Tests Source: https://modern-web.dev/docs/test-runner/cli-and-configuration Demonstrates the usage of the shorthand 'wtr' command for running tests with CLI flags, offering a more concise way to invoke the test runner with specific configurations like esbuild target. ```bash wtr test/**/*.test.js --node-resolve --esbuild-target auto ``` -------------------------------- ### Configure Selenium Launcher for Chrome Headless Source: https://modern-web.dev/docs/test-runner/browser-launchers/selenium This snippet demonstrates how to configure the Selenium launcher for the modern web test runner. It specifies Chrome in headless mode and points to a local Selenium server. Ensure you have `selenium-webdriver` installed. ```javascript import { seleniumLauncher } from '@web/test-runner-selenium'; import webdriver from 'selenium-webdriver'; module.exports = { browsers: seleniumLauncher({ driverBuilder: new webdriver.Builder() .forBrowser('chrome') .setChromeOptions(new ChromeOptions().headless()) .usingServer('http://localhost:4444/wd/hub'), }), }; ``` -------------------------------- ### Proxy API Requests with Koa-Proxies Source: https://modern-web.dev/docs/dev-server/middleware Configure the dev server to proxy requests to an API endpoint using the `koa-proxies` middleware. This is useful for separating frontend development servers from backend API servers. Ensure `koa-proxies` is installed. ```javascript import proxy from 'koa-proxies'; export default { port: 9000, middleware: [ proxy('/api', { target: 'http://localhost:9001', }), ], }; ``` -------------------------------- ### ES Module Configuration (`.mjs`) Source: https://modern-web.dev/docs/test-runner/cli-and-configuration Example of a web test runner configuration file written using ES module syntax. This is the recommended approach for ensuring correct loading, especially in monorepos where `rootDir` needs to be specified. ```javascript export default { concurrency: 10, nodeResolve: true, watch: true, // in a monorepo you need to set set the root dir to resolve modules rootDir: '../../', }; ``` -------------------------------- ### Configure Dot Reporter for Web Test Runner Source: https://modern-web.dev/docs/test-runner/reporters/dot This configuration snippet shows how to integrate the dotReporter from '@web/test-runner' into your Web Test Runner setup. It enables a Mocha-style dot reporter for enhanced test output. No external dependencies beyond '@web/test-runner' are required. ```javascript import { dotReporter } from '@web/test-runner'; export default { nodeResolve: true, reporters: [dotReporter()], }; ``` -------------------------------- ### Run HTML Tests Bare Bones - JavaScript Source: https://modern-web.dev/docs/test-runner/writing-tests/html-tests This snippet shows a bare-bones approach to running HTML tests without a framework. It manually handles test session communication with the test runner, including starting, finishing, and reporting failures. ```javascript ``` -------------------------------- ### Configure WebdriverIO Launchers for Chrome and Firefox Source: https://modern-web.dev/docs/test-runner/browser-launchers/webdriver This configuration sets up WebdriverIO launchers for Chrome and Firefox browsers. It requires a running Selenium server and specifies browser capabilities, including headless mode for both browsers. Ensure you have the necessary WebdriverIO dependencies installed. ```javascript import { webdriverLauncher } from '@web/test-runner-webdriver'; module.exports = { browsers: [ webdriverLauncher({ automationProtocol: 'webdriver', path: '/wd/hub/', capabilities: { browserName: 'chrome', 'goog:chromeOptions': { args: ['--no-sandbox', '--headless'], }, }, }), webdriverLauncher({ automationProtocol: 'webdriver', path: '/wd/hub/', capabilities: { browserName: 'firefox', 'moz:firefoxOptions': { args: ['-headless'], }, }, }), ], }; ``` -------------------------------- ### Run Dev Server in Middleware Mode (Node.js) Source: https://modern-web.dev/docs/dev-server/node-api Enables middleware mode for the dev server, allowing it to be used as a middleware with compatible Node.js servers like Express or Koa. The server does not start its own HTTP server in this mode but provides a callback for integration. ```javascript import { startDevServer } from '@web/dev-server'; async function main() { const expressApp = express(); expressApp.listen(1234); const { koaApp } = await startDevServer({ config: { middlewareMode: true, }, }); expressApp.use(koaApp.callback()); } main(); ``` -------------------------------- ### Import Images with @rollup/plugin-url Source: https://modern-web.dev/docs/dev-server/writing-plugins/examples This snippet illustrates how to import image assets from JavaScript using the `@rollup/plugin-url` plugin. It configures the web dev server to serve asset files as JavaScript. Avoid using the `limit` option with this plugin when used with `@web/dev-server-rollup` as it can cause compatibility issues. ```javascript /* eslint-disable */ import rollupUrl from 'rollup-plugin-url'; import { fromRollup } from '@web/dev-server-rollup'; const url = fromRollup(rollupUrl); export default { // tell the server to serve your assets files as js mimeTypes: { './assets/**/*': 'js', }, plugins: [url({ include: ['assets/**/*.png'] })], }; ```