-
-
Notifications
You must be signed in to change notification settings - Fork 42
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Test(Svelte): CSSRuntimeProvider e2e
- Loading branch information
Showing
10 changed files
with
276 additions
and
49 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
<script lang="ts"> | ||
import { onMount } from 'svelte'; | ||
import { writable } from 'svelte/store' | ||
import type { Config } from '@master/css' | ||
import CSSRuntimeProvider from '../src/lib/CSSRuntimeProvider.svelte' | ||
let containerRef: HTMLDivElement | ||
let shadowRoot: ShadowRoot | ||
const config = writable<Config>({ | ||
styles: { | ||
btn: 'b:2|red' | ||
} | ||
}) | ||
const root = writable<ShadowRoot>() | ||
onMount(() => { | ||
shadowRoot = containerRef.attachShadow({ mode: 'open' }); | ||
const shadowContent = document.createElement('div'); | ||
shadowContent.className = 'f:1000' | ||
shadowRoot.appendChild(shadowContent); | ||
}) | ||
</script> | ||
|
||
<CSSRuntimeProvider config={$config} root={$root}> | ||
<button id="config-btn" class="btn" on:click={() => config.set({})}></button> | ||
<button id="root-btn" on:click={() => root.set(shadowRoot)}></button> | ||
<div bind:this={containerRef}></div> | ||
</CSSRuntimeProvider> | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import { defineConfig, devices } from '@playwright/experimental-ct-svelte' | ||
import { svelte } from '@sveltejs/vite-plugin-svelte' | ||
|
||
export default defineConfig({ | ||
testDir: './', | ||
timeout: 10000, | ||
fullyParallel: true, | ||
forbidOnly: !!process.env.CI, | ||
workers: process.env.CI ? 1 : undefined, | ||
reporter: 'list', | ||
use: { | ||
ctPort: 3100 | ||
}, | ||
projects: [ | ||
{ | ||
name: 'chromium', | ||
use: { ...devices['Desktop Chrome'] }, | ||
}, | ||
{ | ||
name: 'firefox', | ||
use: { ...devices['Desktop Firefox'] }, | ||
}, | ||
{ | ||
name: 'webkit', | ||
use: { ...devices['Desktop Safari'] }, | ||
}, | ||
], | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
<title>Testing Page</title> | ||
</head> | ||
<body> | ||
<div id="root"></div> | ||
<script type="module" src="./index.ts"></script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
// Import styles, initialize component theme here. | ||
// import '../src/common.css'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import { test, expect } from '@playwright/experimental-ct-svelte' | ||
import RuntimeComponent from './Runtime.svelte' | ||
|
||
test('Runtime - class changed', async ({ page, mount }) => { | ||
const runtimeComponentInstance = await mount(RuntimeComponent) | ||
|
||
const $button = await page.$('#config-btn') | ||
await $button?.evaluateHandle(($button) => $button.classList.add('f:10')) | ||
expect(await page.evaluate(() => globalThis.runtimeCSS.classesUsage)).toEqual({ | ||
'btn': 1, | ||
'f:10': 1 | ||
}) | ||
|
||
await runtimeComponentInstance.unmount() | ||
expect(await page.evaluate(() => globalThis.runtimeCSS.style)).toBeNull() | ||
expect(await page.evaluate(() => globalThis.runtimeCSSs.length)).toBe(0) | ||
}) | ||
|
||
test('Runtime - config changed', async ({ page, mount }) => { | ||
await mount(RuntimeComponent) | ||
expect(await page.evaluate(() => globalThis.runtimeCSS.text)).toContain('.btn{border:0.125rem rgb(var(--red)) solid}') | ||
|
||
const $button = await page.$('#config-btn') | ||
await $button?.click() | ||
expect(await page.evaluate(() => globalThis.runtimeCSS.text)).not.toContain('.btn{border:0.125rem rgb(var(--red)) solid}') | ||
}) | ||
|
||
test('Runtime - root changed', async ({ page, mount }) => { | ||
await mount(RuntimeComponent) | ||
|
||
const $button = await page.$('#root-btn') | ||
await $button?.click() | ||
expect(await page.evaluate(() => globalThis.runtimeCSSs[0].classesUsage)).toEqual({ | ||
'f:1000': 1 | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import adapter from '@sveltejs/adapter-auto' | ||
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte' | ||
|
||
/** @type {import('@sveltejs/kit').Config} */ | ||
const config = { | ||
// Consult https://kit.svelte.dev/docs/integrations#preprocessors | ||
// for more information about preprocessors | ||
preprocess: vitePreprocess(), | ||
|
||
kit: { | ||
// adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list. | ||
// If your environment is not supported or you settled on a specific environment, switch out the adapter. | ||
// See https://kit.svelte.dev/docs/adapters for more information about adapters. | ||
adapter: adapter() | ||
} | ||
} | ||
|
||
export default config |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,46 +1,80 @@ | ||
<script lang="ts"> | ||
import type { Config } from "@master/css"; | ||
import RuntimeCSS from "@master/css-runtime"; | ||
import { onMount, setContext } from "svelte"; | ||
import { writable } from "svelte/store"; | ||
import { cssRuntimeSymbol } from "./css-runtime"; | ||
export let config: Config | Promise<Config> | Promise<any> | undefined = undefined; | ||
export let root: Document | ShadowRoot | undefined = undefined; | ||
const runtimeCSS = writable<RuntimeCSS>(); | ||
onMount(() => { | ||
let newCSSRuntime: RuntimeCSS; | ||
if (!$runtimeCSS) { | ||
const init = (resolvedConfig?: Config) => { | ||
const existingCSSRuntime = (globalThis as any).runtimeCSSs.find( | ||
(eachCSS: RuntimeCSS) => eachCSS.root === root | ||
); | ||
if (existingCSSRuntime) { | ||
runtimeCSS.set(existingCSSRuntime); | ||
} else { | ||
newCSSRuntime = new RuntimeCSS(root, resolvedConfig).observe(); | ||
runtimeCSS.set(newCSSRuntime); | ||
} | ||
}; | ||
if (config instanceof Promise) { | ||
(async () => { | ||
const configModule = await config; | ||
init( | ||
configModule?.config || | ||
configModule?.default || | ||
configModule | ||
); | ||
})(); | ||
} else { | ||
init(config); | ||
} | ||
} else if (!$runtimeCSS.observing) { | ||
$runtimeCSS.observe(); | ||
import type { Config } from "@master/css" | ||
import RuntimeCSS from "@master/css-runtime" | ||
import { onMount, setContext, afterUpdate, onDestroy } from "svelte" | ||
import { writable } from "svelte/store" | ||
import { cssRuntimeSymbol } from "./css-runtime" | ||
export let config: Config | Promise<Config> | Promise<any> | undefined = undefined | ||
export let root: Document | ShadowRoot | undefined = undefined | ||
const runtimeCSS = writable<RuntimeCSS>() | ||
let initializing = false | ||
let isExternalRuntimeCSS = false | ||
let identifier = 0 | ||
const getResolvedConfig = async () => { | ||
if (config instanceof Promise) { | ||
const configModule: any = await config | ||
return configModule?.config || configModule?.default || configModule | ||
} else { | ||
return config | ||
} | ||
} | ||
const init = async (resolvedConfig?: Config | undefined) => { | ||
initializing = true | ||
const currentRoot = root ?? document | ||
const existingCSSRuntime = (globalThis as any).runtimeCSSs.find((eachCSS: RuntimeCSS) => eachCSS.root === currentRoot) | ||
if (existingCSSRuntime) { | ||
runtimeCSS.set(existingCSSRuntime) | ||
isExternalRuntimeCSS = true | ||
} else { | ||
runtimeCSS.set(new RuntimeCSS(root, resolvedConfig ?? await getResolvedConfig()).observe()) | ||
isExternalRuntimeCSS = false | ||
} | ||
initializing = false | ||
} | ||
const waitInitialized = async () => { | ||
if (initializing) { | ||
await new Promise<void>((resolve) => { | ||
const interval = setInterval(() => { | ||
if (!initializing) { | ||
clearInterval(interval) | ||
resolve() | ||
} | ||
}, 10) | ||
}) | ||
} | ||
} | ||
onMount(async () => await init()); | ||
afterUpdate(async () => { | ||
const currentIdentifier = ++identifier | ||
await waitInitialized() | ||
if (currentIdentifier !== identifier) | ||
return | ||
const resolvedConfig = await getResolvedConfig() | ||
if ( | ||
$runtimeCSS.root !== root | ||
&& (root || $runtimeCSS.root !== document) | ||
) { | ||
$runtimeCSS.destroy() | ||
await init(resolvedConfig) | ||
} else { | ||
$runtimeCSS.refresh(resolvedConfig) | ||
} | ||
}) | ||
onDestroy(() => { | ||
if (!isExternalRuntimeCSS) { | ||
$runtimeCSS?.destroy() | ||
} | ||
return () => { | ||
newCSSRuntime?.destroy(); | ||
}; | ||
}); | ||
setContext(cssRuntimeSymbol, runtimeCSS); | ||
setContext(cssRuntimeSymbol, runtimeCSS) | ||
</script> | ||
|
||
<slot /> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,40 @@ | ||
<script> | ||
import CSSRuntimeProvider from "../lib/CSSRuntimeProvider.svelte"; | ||
<script lang="ts"> | ||
import { onMount } from 'svelte'; | ||
import { writable } from 'svelte/store' | ||
import type { Config } from '@master/css' | ||
import CSSRuntimeProvider from '../lib/CSSRuntimeProvider.svelte' | ||
let containerRef: HTMLDivElement | ||
let shadowRoot: ShadowRoot | ||
const config = writable<Config>({ | ||
styles: { | ||
btn: 'b:2|red' | ||
} | ||
}) | ||
const root = writable<ShadowRoot>() | ||
const destroy = writable<boolean>(false) | ||
onMount(() => { | ||
shadowRoot = containerRef.attachShadow({ mode: 'open' }); | ||
const shadowContent = document.createElement('div'); | ||
shadowContent.className = 'f:1000' | ||
shadowRoot.appendChild(shadowContent); | ||
}) | ||
</script> | ||
|
||
<CSSRuntimeProvider> | ||
<h1>Welcome to your library project</h1> | ||
<p>Create your package using @sveltejs/package and preview/showcase your work with SvelteKit</p> | ||
<p>Visit <a href="https://kit.svelte.dev">kit.svelte.dev</a> to read the documentation</p> | ||
</CSSRuntimeProvider> | ||
{#if $destroy} | ||
<button on:click={() => destroy.set(false)}>INIT</button> | ||
{/if} | ||
|
||
{#if !$destroy} | ||
<CSSRuntimeProvider config={$config} root={$root}> | ||
<button on:click={() => destroy.set(true)}>DESTROY</button> | ||
<button id="config-btn" class="btn" on:click={() => config.set({})}>CONFIG</button> | ||
<button id="root-btn" on:click={() => root.set(shadowRoot)}>ROOT</button> | ||
<div bind:this={containerRef}></div> | ||
</CSSRuntimeProvider> | ||
{/if} | ||
|
||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.