From ee03658641d772a2fbfca4f0335c6e71d8c43ee6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Wi=C5=9Bniowski?= Date: Tue, 18 Feb 2025 19:47:03 +0100 Subject: [PATCH] refactor: add a svelte4 version of tests --- tests/components/ct-svelte4/.gitignore | 5 + tests/components/ct-svelte4/README.md | 109 ++++++++++++++++ tests/components/ct-svelte4/package.json | 24 ++++ .../ct-svelte4/playwright.config.ts | 49 +++++++ .../ct-svelte4/playwright/index.html | 13 ++ .../components/ct-svelte4/playwright/index.ts | 15 +++ .../components/ct-svelte4/public/favicon.png | Bin 0 -> 3127 bytes tests/components/ct-svelte4/public/index.html | 17 +++ tests/components/ct-svelte4/rollup.config.js | 121 ++++++++++++++++++ .../ct-svelte4/scripts/setupTypeScript.js | 121 ++++++++++++++++++ tests/components/ct-svelte4/src/App.svelte | 34 +++++ .../ct-svelte4/src/assets/index.css | 20 +++ .../ct-svelte4/src/components/Button.svelte | 7 + .../src/components/Component.svelte | 1 + .../ct-svelte4/src/components/Counter.svelte | 14 ++ .../src/components/DefaultSlot.svelte | 9 ++ .../ct-svelte4/src/components/Empty.svelte | 0 .../src/components/MultiRoot.svelte | 2 + .../src/components/NamedSlots.svelte | 11 ++ tests/components/ct-svelte4/src/main.js | 8 ++ .../ct-svelte4/src/pages/DashboardPage.svelte | 1 + .../ct-svelte4/src/pages/LoginPage.svelte | 1 + .../components/ct-svelte4/src/store/index.ts | 4 + .../ct-svelte4/tests/events.spec.ts | 16 +++ .../ct-svelte4/tests/render.spec.ts | 25 ++++ .../ct-svelte4/tests/router.spec.ts | 11 ++ .../components/ct-svelte4/tests/slots.spec.ts | 25 ++++ .../ct-svelte4/tests/unmount.spec.ts | 33 +++++ .../ct-svelte4/tests/update.spec.ts | 32 +++++ tests/components/ct-svelte4/tsconfig.json | 16 +++ 30 files changed, 744 insertions(+) create mode 100644 tests/components/ct-svelte4/.gitignore create mode 100644 tests/components/ct-svelte4/README.md create mode 100644 tests/components/ct-svelte4/package.json create mode 100644 tests/components/ct-svelte4/playwright.config.ts create mode 100644 tests/components/ct-svelte4/playwright/index.html create mode 100644 tests/components/ct-svelte4/playwright/index.ts create mode 100644 tests/components/ct-svelte4/public/favicon.png create mode 100644 tests/components/ct-svelte4/public/index.html create mode 100644 tests/components/ct-svelte4/rollup.config.js create mode 100644 tests/components/ct-svelte4/scripts/setupTypeScript.js create mode 100644 tests/components/ct-svelte4/src/App.svelte create mode 100644 tests/components/ct-svelte4/src/assets/index.css create mode 100644 tests/components/ct-svelte4/src/components/Button.svelte create mode 100644 tests/components/ct-svelte4/src/components/Component.svelte create mode 100644 tests/components/ct-svelte4/src/components/Counter.svelte create mode 100644 tests/components/ct-svelte4/src/components/DefaultSlot.svelte create mode 100644 tests/components/ct-svelte4/src/components/Empty.svelte create mode 100644 tests/components/ct-svelte4/src/components/MultiRoot.svelte create mode 100644 tests/components/ct-svelte4/src/components/NamedSlots.svelte create mode 100644 tests/components/ct-svelte4/src/main.js create mode 100644 tests/components/ct-svelte4/src/pages/DashboardPage.svelte create mode 100644 tests/components/ct-svelte4/src/pages/LoginPage.svelte create mode 100644 tests/components/ct-svelte4/src/store/index.ts create mode 100644 tests/components/ct-svelte4/tests/events.spec.ts create mode 100644 tests/components/ct-svelte4/tests/render.spec.ts create mode 100644 tests/components/ct-svelte4/tests/router.spec.ts create mode 100644 tests/components/ct-svelte4/tests/slots.spec.ts create mode 100644 tests/components/ct-svelte4/tests/unmount.spec.ts create mode 100644 tests/components/ct-svelte4/tests/update.spec.ts create mode 100644 tests/components/ct-svelte4/tsconfig.json diff --git a/tests/components/ct-svelte4/.gitignore b/tests/components/ct-svelte4/.gitignore new file mode 100644 index 0000000000000..2347f3ca3be94 --- /dev/null +++ b/tests/components/ct-svelte4/.gitignore @@ -0,0 +1,5 @@ +/node_modules/ +/public/build/ +/public/tests/ + +.DS_Store diff --git a/tests/components/ct-svelte4/README.md b/tests/components/ct-svelte4/README.md new file mode 100644 index 0000000000000..8ca4fcaff9912 --- /dev/null +++ b/tests/components/ct-svelte4/README.md @@ -0,0 +1,109 @@ +*Psst — looking for a more complete solution? Check out [SvelteKit](https://kit.svelte.dev), the official framework for building web applications of all sizes, with a beautiful development experience and flexible filesystem-based routing.* + +*Looking for a shareable component template instead? You can [use SvelteKit for that as well](https://kit.svelte.dev/docs#packaging) or the older [sveltejs/component-template](https://github.com/sveltejs/component-template)* + +--- + +# svelte app + +This is a project template for [Svelte](https://svelte.dev) apps. It lives at https://github.com/sveltejs/template. + +To create a new project based on this template using [degit](https://github.com/Rich-Harris/degit): + +```bash +npx degit sveltejs/template svelte-app +cd svelte-app +``` + +*Note that you will need to have [Node.js](https://nodejs.org) installed.* + + +## Get started + +Install the dependencies... + +```bash +cd svelte-app +npm install +``` + +...then start [Rollup](https://rollupjs.org): + +```bash +npm run dev +``` + +Navigate to [localhost:8080](http://localhost:8080). You should see your app running. Edit a component file in `src`, save it, and reload the page to see your changes. + +By default, the server will only respond to requests from localhost. To allow connections from other computers, edit the `sirv` commands in package.json to include the option `--host 0.0.0.0`. + +If you're using [Visual Studio Code](https://code.visualstudio.com/) we recommend installing the official extension [Svelte for VS Code](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode). If you are using other editors you may need to install a plugin in order to get syntax highlighting and intellisense. + +## Building and running in production mode + +To create an optimised version of the app: + +```bash +npm run build +``` + +You can run the newly built app with `npm run start`. This uses [sirv](https://github.com/lukeed/sirv), which is included in your package.json's `dependencies` so that the app will work when you deploy to platforms like [Heroku](https://heroku.com). + + +## Single-page app mode + +By default, sirv will only respond to requests that match files in `public`. This is to maximise compatibility with static fileservers, allowing you to deploy your app anywhere. + +If you're building a single-page app (SPA) with multiple routes, sirv needs to be able to respond to requests for *any* path. You can make it so by editing the `"start"` command in package.json: + +```js +"start": "sirv public --single" +``` + +## Using TypeScript + +This template comes with a script to set up a TypeScript development environment, you can run it immediately after cloning the template with: + +```bash +node scripts/setupTypeScript.js +``` + +Or remove the script via: + +```bash +rm scripts/setupTypeScript.js +``` + +If you want to use `baseUrl` or `path` aliases within your `tsconfig`, you need to set up `@rollup/plugin-alias` to tell Rollup to resolve the aliases. For more info, see [this StackOverflow question](https://stackoverflow.com/questions/63427935/setup-tsconfig-path-in-svelte). + +## Deploying to the web + +### With [Vercel](https://vercel.com) + +Install `vercel` if you haven't already: + +```bash +npm install -g vercel +``` + +Then, from within your project folder: + +```bash +cd public +vercel deploy --name my-project +``` + +### With [surge](https://surge.sh/) + +Install `surge` if you haven't already: + +```bash +npm install -g surge +``` + +Then, from within your project folder: + +```bash +npm run build +surge public my-project.surge.sh +``` diff --git a/tests/components/ct-svelte4/package.json b/tests/components/ct-svelte4/package.json new file mode 100644 index 0000000000000..90ac777a15da2 --- /dev/null +++ b/tests/components/ct-svelte4/package.json @@ -0,0 +1,24 @@ +{ + "name": "ct-svelte", + "version": "1.0.0", + "private": true, + "scripts": { + "build": "rollup -c", + "dev": "rollup -c -w", + "start": "sirv public --no-clear", + "typecheck": "tsc --noEmit" + }, + "devDependencies": { + "@rollup/plugin-commonjs": "^17.0.0", + "@rollup/plugin-node-resolve": "^11.0.0", + "rollup": "^2.3.4", + "rollup-plugin-css-only": "^3.1.0", + "rollup-plugin-livereload": "^2.0.0", + "rollup-plugin-svelte": "^7.0.0", + "rollup-plugin-terser": "^7.0.0", + "sirv-cli": "^2.0.0" + }, + "dependencies": { + "svelte": "^5.19.9" + } +} diff --git a/tests/components/ct-svelte4/playwright.config.ts b/tests/components/ct-svelte4/playwright.config.ts new file mode 100644 index 0000000000000..e26caad73687b --- /dev/null +++ b/tests/components/ct-svelte4/playwright.config.ts @@ -0,0 +1,49 @@ +/** + * Copyright (c) Microsoft Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { defineConfig, devices } from '@playwright/experimental-ct-svelte'; +import { resolve } from 'path'; + +export default defineConfig({ + testDir: 'tests', + forbidOnly: !!process.env.CI, + retries: process.env.CI ? 2 : 0, + reporter: process.env.CI ? 'html' : 'line', + use: { + trace: 'on-first-retry', + ctViteConfig: { + resolve: { + alias: { + '@': resolve(__dirname, './src'), + } + } + } + }, + projects: [ + { + name: 'chromium', + use: { ...devices['Desktop Chrome'] }, + }, + { + name: 'firefox', + use: { ...devices['Desktop Firefox'] }, + }, + { + name: 'webkit', + use: { ...devices['Desktop Safari'] }, + }, + ], +}); diff --git a/tests/components/ct-svelte4/playwright/index.html b/tests/components/ct-svelte4/playwright/index.html new file mode 100644 index 0000000000000..43136a165e2a7 --- /dev/null +++ b/tests/components/ct-svelte4/playwright/index.html @@ -0,0 +1,13 @@ + + + + + + + Svelte Test + + +
+ + + diff --git a/tests/components/ct-svelte4/playwright/index.ts b/tests/components/ct-svelte4/playwright/index.ts new file mode 100644 index 0000000000000..fe89c98e10d87 --- /dev/null +++ b/tests/components/ct-svelte4/playwright/index.ts @@ -0,0 +1,15 @@ +// @ts-check +import '../src/assets/index.css'; +import { beforeMount, afterMount } from '@playwright/experimental-ct-svelte/hooks'; + +export type HooksConfig = { + route: string; +} + +beforeMount(async ({ hooksConfig }) => { + console.log(`Before mount: ${JSON.stringify(hooksConfig)}`); +}); + +afterMount(async () => { + console.log(`After mount`); +}); diff --git a/tests/components/ct-svelte4/public/favicon.png b/tests/components/ct-svelte4/public/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..7e6f5eb5a2f1f1c882d265cf479de25caa925645 GIT binary patch literal 3127 zcmV-749N3|P)i z7)}s4L53SJCkR}iVi00SFk;`MXX*#X*kkwKs@nFGS}c;=?XFjU|G$3t^5sjIVS2G+ zw)WGF83CpoGXhLGW(1gW%uV|X7>1P6VhCX=Ux)Lb!*DZ%@I3!{Gsf7d?gtIQ%nQiK z3%(LUSkBji;C5Rfgd6$VsF@H`Pk@xtY6t<>FNR-pD}=C~$?)9pdm3XZ36N5PNWYjb z$xd$yNQR9N!dfj-Vd@BwQo^FIIWPPmT&sZyQ$v81(sCBV=PGy{0wltEjB%~h157*t zvbe_!{=I_783x!0t1-r#-d{Y?ae$Q4N_Nd^Ui^@y(%)Gjou6y<3^XJdu{rmUf-Me?)zZ>9OR&6U5H*cK; z$gUlB{g0O4gN0sLSO|Of?hU(l?;h(jA3uH!Z{EBKuV23ouU@^Y6#%v+QG;>e*E}%?wlu-NT4DG zs)z)7WbLr)vGAu(ohrKc^em@OpO&f~6_>E61n_e0_V3@{U3^O;j{`^mNCJUj_>;7v zsMs6Hu3g7+@v+lSo;=yTYFqq}jZmQ-BK8K{C4kqi_i*jBaQE(Au0607V-zKeT;EPg zX(`vrn=L+e74+-Tqeok@_`tDa$G9I|$nTU5H*2V8@y()n*zqM?J1G!-1aX;CfDC9B zTnJ#j_%*n8Qb1)re*Bno7g0RG{Eb;IK14irJYJp$5Z6ac9~b_P?+5t~95~SRG$g?1 znFJ7p$xV&GZ18m~79TGRdfsc-BcX$9yXTR*n)mPD@1~O(_?cT$ZvFPucRmGlq&se0 zKrcUf^k}4hM*biEJOWKzz!qQe;CB_ZtSOO9Owg#lZAc=s65^rb{fZe(TYu_rk!wKkEf}RIt=#Om( zR8mN`DM<^xj~59euMMspBolVN zAPTr8sSDI104orIAdmL$uOXn*6hga1G+0WD0E?UtabxC#VC~vf3|10|phW;yQ3CY8 z2CM=)ErF;xq-YJ5G|um}>*1#E+O_Mu|Nr#qQ&G1P-NMq@f?@*XUcSbV?tX=)ilM-Q zBZP|!Bpv0V;#ojKcpc7$=eqO;#Uy~#?^kNI{vSZfLx&DEt~LTmaKWXcx=joubklI<*Aw z>LtMaQ7DR<1I2LkWvwyu#Rwn~;ezT}_g(@5l3h?W%-a86Y-t#O1PubP+z<%?V5D(U zy57A6{h+{?kOZp7&WKZR+=sznMJ}+Dnpo=C_0%R_x_t~J5T?E_{+))l5v1%52>)d-`iiZyx|5!%M2Fb2dU zW3~MwwpEH9Rhue+k$UIOoo($Ds!NbOyMR36fRHu;*15(YcA7siIZk#%JWz>P!qX1?IUojG&nKR>^gArBt2 zit(ETyZ=@V&7mv_Fi4bABcnwP+jzQuHcfU&BrAV91u-rFvEi7y-KnWsvHH=d2 zgAk(GKm_S8RcTJ>2N3~&Hbwp{Z3NF_Xeh}g4Eke)V&dY{W(3&b1j9t4yK_aYJisZZ{1rcU5- z;eD>K;ndPq&B-8yA_S0F!4ThA&{1{x)H<#?k9a#6Pc6L?V^s0``ynL&D;p(!Nmx`Y zFkHex{4p!Ggm^@DlehW}iHHVi}~u=$&N? z(NEBLQ#UxxAkdW>X9LnqUr#t4Lu0=9L8&o>JsqTtT5|%gb3QA~hr0pED71+iFFr)dZ=Q=E6ng{NE{Z~0)C?deO#?Aj zSDQ$z#TeC2T^|=}6GBo-&$;E{HL3!q3Z-szuf)O=G#zDjin4SSP%o%6+2IT#sLjQa ziyxFFz~LMjWY+_a5H!U6%a<=b7QVP^ z*90a62;bVq{?@)P6^DWd^Yilq4|YTV2Nw!Yu;a1lPI-sxR)rf@Fe5DhDP7FH zZZ%4S*1C30P;|O+jB!1;m|rXT90Sm5*RBbQN`PKu+hDD*S^yE(CdtSfg=z>u$cIj> z + + + + + + Svelte app + + + + + + + + + + diff --git a/tests/components/ct-svelte4/rollup.config.js b/tests/components/ct-svelte4/rollup.config.js new file mode 100644 index 0000000000000..10b425f1fb9d1 --- /dev/null +++ b/tests/components/ct-svelte4/rollup.config.js @@ -0,0 +1,121 @@ +import svelte from 'rollup-plugin-svelte'; +import commonjs from '@rollup/plugin-commonjs'; +import resolve from '@rollup/plugin-node-resolve'; +import livereload from 'rollup-plugin-livereload'; +import { terser } from 'rollup-plugin-terser'; +import css from 'rollup-plugin-css-only'; + +const production = !process.env.ROLLUP_WATCH; + +function serve() { + let server; + + function toExit() { + if (server) server.kill(0); + } + + return { + writeBundle() { + if (server) return; + server = require('child_process').spawn('npm', ['run', 'start', '--', '--dev'], { + stdio: ['ignore', 'inherit', 'inherit'], + shell: true + }); + + process.on('SIGTERM', toExit); + process.on('exit', toExit); + } + }; +} + +const prod = { + input: 'src/main.js', + output: { + sourcemap: true, + format: 'iife', + name: 'app', + file: 'public/build/bundle.js' + }, + plugins: [ + svelte({ + compilerOptions: { + // enable run-time checks when not in production + dev: !production + } + }), + // we'll extract any component CSS out into + // a separate file - better for performance + css({ output: 'bundle.css' }), + + // If you have external dependencies installed from + // npm, you'll most likely need these plugins. In + // some cases you'll need additional configuration - + // consult the documentation for details: + // https://github.com/rollup/plugins/tree/master/packages/commonjs + resolve({ + browser: true, + dedupe: ['svelte'] + }), + commonjs(), + + // In dev mode, call `npm run start` once + // the bundle has been generated + !production && serve(), + + // Watch the `public` directory and refresh the + // browser on changes when not in production + !production && livereload('public'), + + // If we're building for production (npm run build + // instead of npm run dev), minify + production && terser() + ], + watch: { + clearScreen: false + } +}; + +const test = { + input: 'src/tests.js', + output: { + sourcemap: true, + format: 'iife', + name: 'app', + file: 'public/tests/bundle.js' + }, + plugins: [ + svelte({ + compilerOptions: { + // enable run-time checks when not in production + dev: !production + } + }), + // we'll extract any component CSS out into + // a separate file - better for performance + css({ output: 'bundle.css' }), + + // If you have external dependencies installed from + // npm, you'll most likely need these plugins. In + // some cases you'll need additional configuration - + // consult the documentation for details: + // https://github.com/rollup/plugins/tree/master/packages/commonjs + resolve({ + browser: true, + dedupe: ['svelte'] + }), + commonjs(), + + // Watch the `public` directory and refresh the + // browser on changes when not in production + !production && livereload('public'), + + // If we're building for production (npm run build + // instead of npm run dev), minify + production && terser() + ], + watch: { + clearScreen: false + }, +}; + +export default [ prod, test ]; diff --git a/tests/components/ct-svelte4/scripts/setupTypeScript.js b/tests/components/ct-svelte4/scripts/setupTypeScript.js new file mode 100644 index 0000000000000..e6184aa223822 --- /dev/null +++ b/tests/components/ct-svelte4/scripts/setupTypeScript.js @@ -0,0 +1,121 @@ +// @ts-check + +/** This script modifies the project to support TS code in .svelte files like: + + + + As well as validating the code for CI. + */ + +/** To work on this script: + rm -rf test-template template && git clone sveltejs/template test-template && node scripts/setupTypeScript.js test-template +*/ + +const fs = require("fs") +const path = require("path") +const { argv } = require("process") + +const projectRoot = argv[2] || path.join(__dirname, "..") + +// Add deps to pkg.json +const packageJSON = JSON.parse(fs.readFileSync(path.join(projectRoot, "package.json"), "utf8")) +packageJSON.devDependencies = Object.assign(packageJSON.devDependencies, { + "svelte-check": "^2.0.0", + "svelte-preprocess": "^4.0.0", + "@rollup/plugin-typescript": "^8.0.0", + "typescript": "^4.0.0", + "tslib": "^2.0.0", + "@tsconfig/svelte": "^2.0.0" +}) + +// Add script for checking +packageJSON.scripts = Object.assign(packageJSON.scripts, { + "check": "svelte-check --tsconfig ./tsconfig.json" +}) + +// Write the package JSON +fs.writeFileSync(path.join(projectRoot, "package.json"), JSON.stringify(packageJSON, null, " ")) + +// mv src/main.js to main.ts - note, we need to edit rollup.config.js for this too +const beforeMainJSPath = path.join(projectRoot, "src", "main.js") +const afterMainTSPath = path.join(projectRoot, "src", "main.ts") +fs.renameSync(beforeMainJSPath, afterMainTSPath) + +// Switch the app.svelte file to use TS +const appSveltePath = path.join(projectRoot, "src", "App.svelte") +let appFile = fs.readFileSync(appSveltePath, "utf8") +appFile = appFile.replace(" + +
+ { e.preventDefault(); navigate('/'); }} href='/login'>Login + { e.preventDefault(); navigate('/dashboard'); }} href='/dashboard'>Dashboard +
+{#if path === '/'} + +{:else if path === '/dashboard'} + +{/if} diff --git a/tests/components/ct-svelte4/src/assets/index.css b/tests/components/ct-svelte4/src/assets/index.css new file mode 100644 index 0000000000000..97495c44b8634 --- /dev/null +++ b/tests/components/ct-svelte4/src/assets/index.css @@ -0,0 +1,20 @@ +body { + margin: 0; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', + 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', + sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +code { + font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', + monospace; +} + +@media (prefers-color-scheme: light) { + :root { + color: #e3e3e3; + background-color: #1b1b1d; + } +} diff --git a/tests/components/ct-svelte4/src/components/Button.svelte b/tests/components/ct-svelte4/src/components/Button.svelte new file mode 100644 index 0000000000000..8c46efd1f2549 --- /dev/null +++ b/tests/components/ct-svelte4/src/components/Button.svelte @@ -0,0 +1,7 @@ + + + diff --git a/tests/components/ct-svelte4/src/components/Component.svelte b/tests/components/ct-svelte4/src/components/Component.svelte new file mode 100644 index 0000000000000..179f993315f43 --- /dev/null +++ b/tests/components/ct-svelte4/src/components/Component.svelte @@ -0,0 +1 @@ +
test
diff --git a/tests/components/ct-svelte4/src/components/Counter.svelte b/tests/components/ct-svelte4/src/components/Counter.svelte new file mode 100644 index 0000000000000..38674bb6c365e --- /dev/null +++ b/tests/components/ct-svelte4/src/components/Counter.svelte @@ -0,0 +1,14 @@ + + + diff --git a/tests/components/ct-svelte4/src/components/DefaultSlot.svelte b/tests/components/ct-svelte4/src/components/DefaultSlot.svelte new file mode 100644 index 0000000000000..201dda6ce3f33 --- /dev/null +++ b/tests/components/ct-svelte4/src/components/DefaultSlot.svelte @@ -0,0 +1,9 @@ +
+

Welcome!

+
+ +
+
+ Thanks for visiting. +
+
diff --git a/tests/components/ct-svelte4/src/components/Empty.svelte b/tests/components/ct-svelte4/src/components/Empty.svelte new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/tests/components/ct-svelte4/src/components/MultiRoot.svelte b/tests/components/ct-svelte4/src/components/MultiRoot.svelte new file mode 100644 index 0000000000000..87996d0ce0062 --- /dev/null +++ b/tests/components/ct-svelte4/src/components/MultiRoot.svelte @@ -0,0 +1,2 @@ +
root 1
+
root 2
diff --git a/tests/components/ct-svelte4/src/components/NamedSlots.svelte b/tests/components/ct-svelte4/src/components/NamedSlots.svelte new file mode 100644 index 0000000000000..5f0d988af511e --- /dev/null +++ b/tests/components/ct-svelte4/src/components/NamedSlots.svelte @@ -0,0 +1,11 @@ +
+
+ +
+
+ +
+
+ +
+
diff --git a/tests/components/ct-svelte4/src/main.js b/tests/components/ct-svelte4/src/main.js new file mode 100644 index 0000000000000..e08102368814c --- /dev/null +++ b/tests/components/ct-svelte4/src/main.js @@ -0,0 +1,8 @@ +import App from './App.svelte'; +import './assets/index.css'; + +const app = new App({ + target: document.body, +}); + +export default app; diff --git a/tests/components/ct-svelte4/src/pages/DashboardPage.svelte b/tests/components/ct-svelte4/src/pages/DashboardPage.svelte new file mode 100644 index 0000000000000..161f5338e8871 --- /dev/null +++ b/tests/components/ct-svelte4/src/pages/DashboardPage.svelte @@ -0,0 +1 @@ +
Dashboard
diff --git a/tests/components/ct-svelte4/src/pages/LoginPage.svelte b/tests/components/ct-svelte4/src/pages/LoginPage.svelte new file mode 100644 index 0000000000000..3c359ab27c9ad --- /dev/null +++ b/tests/components/ct-svelte4/src/pages/LoginPage.svelte @@ -0,0 +1 @@ +
Login
diff --git a/tests/components/ct-svelte4/src/store/index.ts b/tests/components/ct-svelte4/src/store/index.ts new file mode 100644 index 0000000000000..43d7ee31fc435 --- /dev/null +++ b/tests/components/ct-svelte4/src/store/index.ts @@ -0,0 +1,4 @@ +export let remountCount = 0; +export function update() { + remountCount++; +} diff --git a/tests/components/ct-svelte4/tests/events.spec.ts b/tests/components/ct-svelte4/tests/events.spec.ts new file mode 100644 index 0000000000000..f2f2593515464 --- /dev/null +++ b/tests/components/ct-svelte4/tests/events.spec.ts @@ -0,0 +1,16 @@ +import { test, expect } from '@playwright/experimental-ct-svelte'; +import Button from '@/components/Button.svelte'; + +test('emit an submit event when the button is clicked', async ({ mount }) => { + const messages: string[] = []; + const component = await mount(Button, { + props: { + title: 'Submit', + }, + on: { + submit: (data: string) => messages.push(data), + }, + }); + await component.click(); + expect(messages).toEqual(['hello']); +}); diff --git a/tests/components/ct-svelte4/tests/render.spec.ts b/tests/components/ct-svelte4/tests/render.spec.ts new file mode 100644 index 0000000000000..3c0ada7a61949 --- /dev/null +++ b/tests/components/ct-svelte4/tests/render.spec.ts @@ -0,0 +1,25 @@ +import { test, expect } from '@playwright/experimental-ct-svelte'; +import Button from '@/components/Button.svelte'; +import Component from '@/components/Component.svelte'; +import Empty from '@/components/Empty.svelte'; + +test('render props', async ({ mount }) => { + const component = await mount(Button, { + props: { + title: 'Submit', + }, + }); + await expect(component).toContainText('Submit'); +}); + +test('render a component without options', async ({ mount }) => { + const component = await mount(Component); + await expect(component).toContainText('test'); +}); + +test('get textContent of the empty component', async ({ mount }) => { + const component = await mount(Empty); + expect(await component.allTextContents()).toEqual(['']); + expect(await component.textContent()).toBe(''); + await expect(component).toHaveText(''); +}); diff --git a/tests/components/ct-svelte4/tests/router.spec.ts b/tests/components/ct-svelte4/tests/router.spec.ts new file mode 100644 index 0000000000000..127620b3c9fb5 --- /dev/null +++ b/tests/components/ct-svelte4/tests/router.spec.ts @@ -0,0 +1,11 @@ +import { test, expect } from '@playwright/experimental-ct-svelte'; +import App from '@/App.svelte'; + +test('navigate to a page by clicking a link', async ({ page, mount }) => { + const component = await mount(App); + await expect(component.getByRole('main')).toHaveText('Login'); + await expect(page).toHaveURL('/'); + await component.getByRole('link', { name: 'Dashboard' }).click(); + await expect(component.getByRole('main')).toHaveText('Dashboard'); + await expect(page).toHaveURL('/dashboard'); +}); diff --git a/tests/components/ct-svelte4/tests/slots.spec.ts b/tests/components/ct-svelte4/tests/slots.spec.ts new file mode 100644 index 0000000000000..4d6823abe75a5 --- /dev/null +++ b/tests/components/ct-svelte4/tests/slots.spec.ts @@ -0,0 +1,25 @@ +import { test, expect } from '@playwright/experimental-ct-svelte'; +import DefaultSlot from '@/components/DefaultSlot.svelte'; +import NamedSlots from '@/components/NamedSlots.svelte'; + +test('render a default slot', async ({ mount }) => { + const component = await mount(DefaultSlot, { + slots: { + default: 'Main Content', + }, + }); + await expect(component).toContainText('Main Content'); +}); + +test('render a component with a named slot', async ({ mount }) => { + const component = await mount(NamedSlots, { + slots: { + header: 'Header', + main: 'Main Content', + footer: 'Footer', + }, + }); + await expect(component).toContainText('Header'); + await expect(component).toContainText('Main Content'); + await expect(component).toContainText('Footer'); +}); diff --git a/tests/components/ct-svelte4/tests/unmount.spec.ts b/tests/components/ct-svelte4/tests/unmount.spec.ts new file mode 100644 index 0000000000000..c0ac0f678507d --- /dev/null +++ b/tests/components/ct-svelte4/tests/unmount.spec.ts @@ -0,0 +1,33 @@ +import { test, expect } from '@playwright/experimental-ct-svelte'; +import Button from '@/components/Button.svelte'; +import MultiRoot from '@/components/MultiRoot.svelte'; + +test('unmount', async ({ page, mount }) => { + const component = await mount(Button, { + props: { + title: 'Submit', + }, + }); + await expect(page.locator('#root')).toContainText('Submit'); + await component.unmount(); + await expect(page.locator('#root')).not.toContainText('Submit'); +}); + +test('unmount a multi root component', async ({ page, mount }) => { + const component = await mount(MultiRoot); + await expect(page.locator('#root')).toContainText('root 1'); + await expect(page.locator('#root')).toContainText('root 2'); + await component.unmount(); + await expect(page.locator('#root')).not.toContainText('root 1'); + await expect(page.locator('#root')).not.toContainText('root 2'); +}); + +test('unmount twice throws an error', async ({ mount }) => { + const component = await mount(Button, { + props: { + title: 'Submit', + }, + }); + await component.unmount(); + await expect(component.unmount()).rejects.toThrowError('Component was not mounted'); +}); diff --git a/tests/components/ct-svelte4/tests/update.spec.ts b/tests/components/ct-svelte4/tests/update.spec.ts new file mode 100644 index 0000000000000..358204edfaed6 --- /dev/null +++ b/tests/components/ct-svelte4/tests/update.spec.ts @@ -0,0 +1,32 @@ +import { test, expect } from '@playwright/experimental-ct-svelte'; +import Counter from '@/components/Counter.svelte'; + +test('update props without remounting', async ({ mount }) => { + const component = await mount(Counter, { + props: { count: 9001 }, + }); + await expect(component.getByTestId('props')).toContainText('9001'); + + await component.update({ + props: { count: 1337 }, + }); + await expect(component).not.toContainText('9001'); + await expect(component.getByTestId('props')).toContainText('1337'); + + await expect(component.getByTestId('remount-count')).toContainText('1'); +}); + +test('update event listeners without remounting', async ({ mount }) => { + const component = await mount(Counter); + + const messages: string[] = []; + await component.update({ + on: { + submit: (data: string) => messages.push(data), + }, + }); + await component.click(); + expect(messages).toEqual(['hello']); + + await expect(component.getByTestId('remount-count')).toContainText('1'); +}); diff --git a/tests/components/ct-svelte4/tsconfig.json b/tests/components/ct-svelte4/tsconfig.json new file mode 100644 index 0000000000000..4ce7ec19bfd6f --- /dev/null +++ b/tests/components/ct-svelte4/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "target": "ESNext", + "module": "ESNext", + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "skipLibCheck": true, + "moduleResolution": "node", + "baseUrl": ".", + "paths": { + "@/*": ["./src/*"], + "*": ["_"], + } + } +}