Adding E2E tests for client hydration and HMR (#3374)
* adding Tailwind E2E tests with Playwright * package.json updates * adding e2e tests to CI workflow * using e2e for dev tests, mocha for build tests * refactor: sharing test-utils helpers * chore: update lockfile * Adding contributing docs * Revert "refactor: sharing test-utils helpers" This reverts commit 48496f43bc99eab30747baf6e83041ba4932e786. * refactor: simpler solution to resolving e2e test fixtures * chore: updating lockfile * refactor: cleaning up how URLs are resolved in e2e tests * install playwright deps in CI * ensure playwright deps are installed during CI * adding a basic HMR test for tailwind styles * using @e2e for playwright test packages * adding react hydration and HMR tests * adding hydration and HMR tests for preact * adding svelte hydration and HMR tests * adding solid-js hydration and HMR tests * adding solid hydration and HMR tests * adding vue hydration and HMR tests * adding client:media tests * fixing Lit hydration and HMR tests * fixing up the Vue e2e tests * fixing up svelte tests * chore: test cleanup * chore: cleaning up test element IDs * chore: updating lock file * chore: update lockfile after merge * TEMP: disabling React e2e tests * Revert "TEMP: disabling React e2e tests" This reverts commited1bad9cbc
. * updating to use the new editFiles helper * chore: updating lock file * updating lock file * updating lockfile * TEMP: watching for console logs * TEMP: testing typescript tests * updating test:e2e scripts for config file * seems like it didn't find the config file? * use a fresh dev server for each test * removing Lit tests for now * Revert "removing Lit tests for now" This reverts commit4970a8093e
. * updating test config for CI * WIP: disabling HMR tests to track down why they're unreliable * TEMP: logging to debug HMR test * afterEach isn't a global in Playwright * fix: the test's file reset helper was using a URL not filepath * one last try, why is the HMR test hanging at cleanup? * resetting files after tailwind HMR test * create the onNextChange watcher before editFile is called * moving the file changed sync into editFile() * code refactor + Astro Component HMR test * chore: lint fixes * adding a test suite for the framework-multiple example app
This commit is contained in:
parent
63c26c1b24
commit
ff56f083bc
70 changed files with 2183 additions and 105 deletions
|
@ -6,5 +6,5 @@
|
|||
"access": "public",
|
||||
"baseBranch": "main",
|
||||
"updateInternalDependencies": "patch",
|
||||
"ignore": ["@example/*", "@test/*"]
|
||||
"ignore": ["@example/*", "@test/*", "@e2e/*"]
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
"test:smoke": "node scripts/smoke/index.js",
|
||||
"test:vite-ci": "turbo run test --no-deps --scope=astro --concurrency=1",
|
||||
"test:e2e": "cd packages/astro && pnpm playwright install && pnpm run test:e2e",
|
||||
"test:e2e:match": "cd packages/astro && pnpm playwright install && pnpm run test:e2e:match",
|
||||
"benchmark": "turbo run benchmark --scope=astro",
|
||||
"lint": "eslint \"packages/**/*.ts\"",
|
||||
"format": "prettier -w .",
|
||||
|
|
42
packages/astro/e2e/astro-component.test.js
Normal file
42
packages/astro/e2e/astro-component.test.js
Normal file
|
@ -0,0 +1,42 @@
|
|||
import { test as base, expect } from '@playwright/test';
|
||||
import { loadFixture } from './test-utils.js';
|
||||
|
||||
const test = base.extend({
|
||||
astro: async ({}, use) => {
|
||||
const fixture = await loadFixture({ root: './fixtures/astro-component/' });
|
||||
await use(fixture);
|
||||
},
|
||||
});
|
||||
|
||||
let devServer;
|
||||
|
||||
test.beforeEach(async ({ astro }) => {
|
||||
devServer = await astro.startDevServer();
|
||||
});
|
||||
|
||||
test.afterEach(async () => {
|
||||
await devServer.stop();
|
||||
});
|
||||
|
||||
test.describe('Astro components', () => {
|
||||
test('HMR', async ({ page, astro }) => {
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
const hero = page.locator('section');
|
||||
await expect(hero, 'hero has background: white').toHaveCSS(
|
||||
'background-color',
|
||||
'rgb(255, 255, 255)'
|
||||
);
|
||||
await expect(hero, 'hero has color: black').toHaveCSS('color', 'rgb(0, 0, 0)');
|
||||
|
||||
// Edit the Hero component with a new background color
|
||||
await astro.editFile('./src/components/Hero.astro', (content) =>
|
||||
content.replace('background: white', 'background: rgb(230, 230, 230)')
|
||||
);
|
||||
|
||||
await expect(hero, 'background color updated').toHaveCSS(
|
||||
'background-color',
|
||||
'rgb(230, 230, 230)'
|
||||
);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,4 @@
|
|||
import { defineConfig } from 'astro/config';
|
||||
|
||||
// https://astro.build/config
|
||||
export default defineConfig({});
|
8
packages/astro/e2e/fixtures/astro-component/package.json
Normal file
8
packages/astro/e2e/fixtures/astro-component/package.json
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"name": "@e2e/astro-component",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"astro": "workspace:*"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
.counter {
|
||||
display: grid;
|
||||
font-size: 2em;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
margin-top: 2em;
|
||||
place-items: center;
|
||||
}
|
||||
|
||||
.counter-message {
|
||||
text-align: center;
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
import { h, Fragment } from 'preact';
|
||||
import { useState } from 'preact/hooks';
|
||||
import './Counter.css';
|
||||
|
||||
export default function Counter({ children, count: initialCount, id }) {
|
||||
const [count, setCount] = useState(initialCount);
|
||||
const add = () => setCount((i) => i + 1);
|
||||
const subtract = () => setCount((i) => i - 1);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div id={id} className="counter">
|
||||
<button className="decrement" onClick={subtract}>-</button>
|
||||
<pre>{count}</pre>
|
||||
<button className="increment" onClick={add}>+</button>
|
||||
</div>
|
||||
<div className="counter-message">{children}</div>
|
||||
</>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
---
|
||||
export interface Props {
|
||||
title: string;
|
||||
}
|
||||
|
||||
const { title } = Astro.props as Props;
|
||||
---
|
||||
|
||||
<section>
|
||||
<h1>{title}</h1>
|
||||
<slot />
|
||||
</section>
|
||||
|
||||
<style>
|
||||
section {
|
||||
width: 100%;
|
||||
height: 80vh;
|
||||
background: white;
|
||||
color: black;
|
||||
}
|
||||
|
||||
h1 {
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,5 @@
|
|||
import { h } from 'preact';
|
||||
|
||||
export default function({ id }) {
|
||||
return <div id={id}>Preact client:only component</div>
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
---
|
||||
import Hero from '../components/Hero.astro';
|
||||
---
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<!-- Head Stuff -->
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<Hero title="Astro Components">
|
||||
Lorem ipsum, dolor sit amet consectetur adipisicing elit.
|
||||
</Hero>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,7 @@
|
|||
import { defineConfig } from 'astro/config';
|
||||
import lit from '@astrojs/lit';
|
||||
|
||||
// https://astro.build/config
|
||||
export default defineConfig({
|
||||
integrations: [lit()],
|
||||
});
|
11
packages/astro/e2e/fixtures/lit-component/package.json
Normal file
11
packages/astro/e2e/fixtures/lit-component/package.json
Normal file
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"name": "@e2e/lit-component",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@astrojs/lit": "workspace:*",
|
||||
"astro": "workspace:*",
|
||||
"@webcomponents/template-shadowroot": "^0.1.0",
|
||||
"lit": "^2.2.3"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
import { LitElement, html } from 'lit';
|
||||
|
||||
export const tagName = 'my-counter';
|
||||
|
||||
class Counter extends LitElement {
|
||||
static get properties() {
|
||||
return {
|
||||
count: {
|
||||
type: Number,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.count = 0;
|
||||
}
|
||||
|
||||
increment() {
|
||||
this.count++;
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<div>
|
||||
<p>Count: ${this.count}</p>
|
||||
|
||||
<button type="button" @click=${this.increment}>Increment</button>
|
||||
|
||||
<slot />
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(tagName, Counter);
|
|
@ -0,0 +1,26 @@
|
|||
---
|
||||
import '../components/Counter.js';
|
||||
|
||||
const someProps = {
|
||||
count: 0,
|
||||
};
|
||||
---
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<!-- Head Stuff -->
|
||||
</head>
|
||||
<body>
|
||||
<my-counter id="client-idle" {...someProps} client:idle>
|
||||
<h1>Hello, client:idle!</h1>
|
||||
</my-counter>
|
||||
|
||||
<my-counter id="client-load" {...someProps} client:load>
|
||||
<h1>Hello, client:load!</h1>
|
||||
</my-counter>
|
||||
|
||||
<my-counter id="client-visible" {...someProps} client:visible>
|
||||
<h1>Hello, client:visible!</h1>
|
||||
</my-counter>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,18 @@
|
|||
---
|
||||
import '../components/Counter.js';
|
||||
|
||||
const someProps = {
|
||||
count: 0,
|
||||
};
|
||||
---
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<!-- Head Stuff -->
|
||||
</head>
|
||||
<body>
|
||||
<my-counter id="client-media" {...someProps} client:media="(max-width: 50em)">
|
||||
<h1>Hello, client:media!</h1>
|
||||
</my-counter>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,12 @@
|
|||
import { defineConfig } from 'astro/config';
|
||||
import preact from '@astrojs/preact';
|
||||
import react from '@astrojs/react';
|
||||
import svelte from '@astrojs/svelte';
|
||||
import vue from '@astrojs/vue';
|
||||
import solid from '@astrojs/solid-js';
|
||||
|
||||
// https://astro.build/config
|
||||
export default defineConfig({
|
||||
// Enable many frameworks to support all different kinds of components.
|
||||
integrations: [preact(), react(), svelte(), vue(), solid()],
|
||||
});
|
24
packages/astro/e2e/fixtures/multiple-frameworks/package.json
Normal file
24
packages/astro/e2e/fixtures/multiple-frameworks/package.json
Normal file
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"name": "@e2e/multiple-frameworks",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"devDependencies": {
|
||||
"@astrojs/lit": "^0.1.3",
|
||||
"@astrojs/preact": "^0.1.2",
|
||||
"@astrojs/react": "^0.1.2",
|
||||
"@astrojs/solid-js": "^0.1.2",
|
||||
"@astrojs/svelte": "^0.1.3",
|
||||
"@astrojs/vue": "^0.1.4",
|
||||
"astro": "^1.0.0-beta.31"
|
||||
},
|
||||
"dependencies": {
|
||||
"@webcomponents/template-shadowroot": "^0.1.0",
|
||||
"lit": "^2.2.4",
|
||||
"preact": "^10.7.2",
|
||||
"react": "^18.1.0",
|
||||
"react-dom": "^18.1.0",
|
||||
"solid-js": "^1.4.2",
|
||||
"svelte": "^3.48.0",
|
||||
"vue": "^3.2.34"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
const { id } = Astro.props
|
||||
---
|
||||
|
||||
<div id={id} class="children">
|
||||
<h1>Hello Astro (A)</h1>
|
||||
</div>
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
const { id } = Astro.props
|
||||
---
|
||||
|
||||
<div id={id} class="children">
|
||||
<h1>Hello Astro (B)</h1>
|
||||
</div>
|
|
@ -0,0 +1,33 @@
|
|||
import { LitElement, html } from 'lit';
|
||||
|
||||
export const tagName = 'my-counter';
|
||||
|
||||
class Counter extends LitElement {
|
||||
static get properties() {
|
||||
return {
|
||||
count: {
|
||||
type: Number,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.count = 0;
|
||||
}
|
||||
|
||||
increment() {
|
||||
this.count++;
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<div>
|
||||
<p>Count: ${this.count}</p>
|
||||
<button type="button" @click=${this.increment}>Increment</button>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(tagName, Counter);
|
|
@ -0,0 +1,19 @@
|
|||
import { useState } from 'preact/hooks';
|
||||
|
||||
/** a counter written in Preact */
|
||||
export function PreactCounter({ children, id }) {
|
||||
const [count, setCount] = useState(0);
|
||||
const add = () => setCount((i) => i + 1);
|
||||
const subtract = () => setCount((i) => i - 1);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div id={id} class="counter">
|
||||
<button class="decrement" onClick={subtract}>-</button>
|
||||
<pre>{count}</pre>
|
||||
<button class="increment" onClick={add}>+</button>
|
||||
</div>
|
||||
<div class="counter-message">{children}</div>
|
||||
</>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
import { useState } from 'react';
|
||||
|
||||
/** a counter written in React */
|
||||
export function Counter({ children, id }) {
|
||||
const [count, setCount] = useState(0);
|
||||
const add = () => setCount((i) => i + 1);
|
||||
const subtract = () => setCount((i) => i - 1);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div id={id} className="counter">
|
||||
<button className="decrement" onClick={subtract}>-</button>
|
||||
<pre>{count}</pre>
|
||||
<button className="increment" onClick={add}>+</button>
|
||||
</div>
|
||||
<div className="counter-message">{children}</div>
|
||||
</>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
import { createSignal } from 'solid-js';
|
||||
|
||||
/** a counter written with Solid */
|
||||
export default function SolidCounter({ children, id }) {
|
||||
const [count, setCount] = createSignal(0);
|
||||
const add = () => setCount(count() + 1);
|
||||
const subtract = () => setCount(count() - 1);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div id={id} class="counter">
|
||||
<button class="decrement" onClick={subtract}>-</button>
|
||||
<pre>{count()}</pre>
|
||||
<button class="increment" onClick={add}>+</button>
|
||||
</div>
|
||||
<div class="counter-message">{children}</div>
|
||||
</>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
|
||||
<script>
|
||||
export let id;
|
||||
let children;
|
||||
let count = 0;
|
||||
|
||||
function add() {
|
||||
count += 1;
|
||||
}
|
||||
|
||||
function subtract() {
|
||||
count -= 1;
|
||||
}
|
||||
</script>
|
||||
|
||||
<div {id} class="counter">
|
||||
<button class="decrement" on:click={subtract}>-</button>
|
||||
<pre>{ count }</pre>
|
||||
<button class="increment" on:click={add}>+</button>
|
||||
</div>
|
||||
<div class="counter-message">
|
||||
<slot />
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.counter {
|
||||
background: white;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,34 @@
|
|||
<template>
|
||||
<div :id="id" class="counter">
|
||||
<button class="decrement" @click="subtract()">-</button>
|
||||
<pre>{{ count }}</pre>
|
||||
<button class="increment" @click="add()">+</button>
|
||||
</div>
|
||||
<div class="counter-message">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref } from 'vue';
|
||||
export default {
|
||||
props: {
|
||||
id: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
setup(props) {
|
||||
const count = ref(0);
|
||||
const add = () => (count.value = count.value + 1);
|
||||
const subtract = () => (count.value = count.value - 1);
|
||||
|
||||
return {
|
||||
id: props.id,
|
||||
count,
|
||||
add,
|
||||
subtract,
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
|
@ -0,0 +1,2 @@
|
|||
export { default as A } from './A.astro';
|
||||
export { default as B } from './B.astro';
|
|
@ -0,0 +1,50 @@
|
|||
---
|
||||
// Style Imports
|
||||
import '../styles/global.css';
|
||||
// Component Imports
|
||||
import { A, B as Renamed } from '../components';
|
||||
import * as react from '../components/ReactCounter.jsx';
|
||||
import { PreactCounter } from '../components/PreactCounter.tsx';
|
||||
import SolidCounter from '../components/SolidCounter.tsx';
|
||||
import VueCounter from '../components/VueCounter.vue';
|
||||
import SvelteCounter from '../components/SvelteCounter.svelte';
|
||||
|
||||
// Full Astro Component Syntax:
|
||||
// https://docs.astro.build/core-concepts/astro-components/
|
||||
---
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<react.Counter id="react-counter" client:idle>
|
||||
<h1>Hello React!</h1>
|
||||
<p>What's up?</p>
|
||||
</react.Counter>
|
||||
|
||||
<PreactCounter id="preact-counter" client:idle>
|
||||
<h1>Hello Preact!</h1>
|
||||
</PreactCounter>
|
||||
|
||||
<SolidCounter id="solid-counter" client:idle>
|
||||
<h1>Hello Solid!</h1>
|
||||
</SolidCounter>
|
||||
|
||||
<VueCounter id="vue-counter" client:idle>
|
||||
<h1>Hello Vue!</h1>
|
||||
</VueCounter>
|
||||
|
||||
<SvelteCounter id="svelte-counter" client:idle>
|
||||
<h1>Hello Svelte!</h1>
|
||||
</SvelteCounter>
|
||||
|
||||
<A id="astro-a" />
|
||||
|
||||
<Renamed id="astro-b" />
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,21 @@
|
|||
html,
|
||||
body {
|
||||
font-family: system-ui;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
.counter {
|
||||
display: grid;
|
||||
font-size: 2em;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
margin-top: 2em;
|
||||
place-items: center;
|
||||
}
|
||||
|
||||
.counter-message {
|
||||
text-align: center;
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
import { defineConfig } from 'astro/config';
|
||||
import preact from '@astrojs/preact';
|
||||
|
||||
// https://astro.build/config
|
||||
export default defineConfig({
|
||||
integrations: [preact()],
|
||||
});
|
10
packages/astro/e2e/fixtures/preact-component/package.json
Normal file
10
packages/astro/e2e/fixtures/preact-component/package.json
Normal file
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"name": "@e2e/preact-component",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@astrojs/preact": "workspace:*",
|
||||
"astro": "workspace:*",
|
||||
"preact": "^10.7.2"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
.counter {
|
||||
display: grid;
|
||||
font-size: 2em;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
margin-top: 2em;
|
||||
place-items: center;
|
||||
}
|
||||
|
||||
.counter-message {
|
||||
text-align: center;
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
import { h, Fragment } from 'preact';
|
||||
import { useState } from 'preact/hooks';
|
||||
import './Counter.css';
|
||||
|
||||
export default function Counter({ children, count: initialCount, id }) {
|
||||
const [count, setCount] = useState(initialCount);
|
||||
const add = () => setCount((i) => i + 1);
|
||||
const subtract = () => setCount((i) => i - 1);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div id={id} className="counter">
|
||||
<button className="decrement" onClick={subtract}>-</button>
|
||||
<pre>{count}</pre>
|
||||
<button className="increment" onClick={add}>+</button>
|
||||
</div>
|
||||
<div className="counter-message">{children}</div>
|
||||
</>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
import { h } from 'preact';
|
||||
|
||||
export default function({ id }) {
|
||||
return <div id={id}>Preact client:only component</div>
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
---
|
||||
import Counter from '../components/Counter.jsx';
|
||||
import PreactComponent from '../components/JSXComponent.jsx';
|
||||
|
||||
const someProps = {
|
||||
count: 0,
|
||||
};
|
||||
---
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<!-- Head Stuff -->
|
||||
</head>
|
||||
<body>
|
||||
<Counter id="server-only" {...someProps}>
|
||||
<h1>Hello, server!</h1>
|
||||
</Counter>
|
||||
|
||||
<Counter id="client-idle" {...someProps} client:idle>
|
||||
<h1>Hello, client:idle!</h1>
|
||||
</Counter>
|
||||
|
||||
<Counter id="client-load" {...someProps} client:load>
|
||||
<h1>Hello, client:load!</h1>
|
||||
</Counter>
|
||||
|
||||
<Counter id="client-visible" {...someProps} client:visible>
|
||||
<h1>Hello, client:visible!</h1>
|
||||
</Counter>
|
||||
|
||||
<Counter id="client-media" {...someProps} client:media="(max-width: 50em)">
|
||||
<h1>Hello, client:media!</h1>
|
||||
</Counter>
|
||||
|
||||
<PreactComponent id="client-only" client:only="preact" />
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,7 @@
|
|||
import { defineConfig } from 'astro/config';
|
||||
import react from '@astrojs/react';
|
||||
|
||||
// https://astro.build/config
|
||||
export default defineConfig({
|
||||
integrations: [react()],
|
||||
});
|
11
packages/astro/e2e/fixtures/react-component/package.json
Normal file
11
packages/astro/e2e/fixtures/react-component/package.json
Normal file
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"name": "@e2e/react-component",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@astrojs/react": "workspace:*",
|
||||
"astro": "workspace:*",
|
||||
"react": "^18.1.0",
|
||||
"react-dom": "^18.1.0"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
.counter {
|
||||
display: grid;
|
||||
font-size: 2em;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
margin-top: 2em;
|
||||
place-items: center;
|
||||
}
|
||||
|
||||
.counter-message {
|
||||
text-align: center;
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
import React, { useState } from 'react';
|
||||
import './Counter.css';
|
||||
|
||||
export default function Counter({ children, count: initialCount, id }) {
|
||||
const [count, setCount] = useState(initialCount);
|
||||
const add = () => setCount((i) => i + 1);
|
||||
const subtract = () => setCount((i) => i - 1);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div id={id} className="counter">
|
||||
<button className="decrement" onClick={subtract}>-</button>
|
||||
<pre>{count}</pre>
|
||||
<button className="increment" onClick={add}>+</button>
|
||||
</div>
|
||||
<div className="counter-message">{children}</div>
|
||||
</>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
import React from 'react';
|
||||
|
||||
export default function({ id }) {
|
||||
return <div id={id}>React client:only component</div>
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
---
|
||||
import Counter from '../components/Counter.jsx';
|
||||
import ReactComponent from '../components/JSXComponent.jsx';
|
||||
|
||||
const someProps = {
|
||||
count: 0,
|
||||
};
|
||||
---
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<!-- Head Stuff -->
|
||||
</head>
|
||||
<body>
|
||||
<Counter id="server-only" {...someProps}>
|
||||
<h1>Hello, server!</h1>
|
||||
</Counter>
|
||||
|
||||
<Counter id="client-idle" {...someProps} client:idle>
|
||||
<h1>Hello, client:idle!</h1>
|
||||
</Counter>
|
||||
|
||||
<Counter id="client-load" {...someProps} client:load>
|
||||
<h1>Hello, client:load!</h1>
|
||||
</Counter>
|
||||
|
||||
<Counter id="client-visible" {...someProps} client:visible>
|
||||
<h1>Hello, client:visible!</h1>
|
||||
</Counter>
|
||||
|
||||
<Counter id="client-media" {...someProps} client:media="(max-width: 50em)">
|
||||
<h1>Hello, client:media!</h1>
|
||||
</Counter>
|
||||
|
||||
<ReactComponent id="client-only" client:only="react" />
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,7 @@
|
|||
import { defineConfig } from 'astro/config';
|
||||
import solid from '@astrojs/solid-js';
|
||||
|
||||
// https://astro.build/config
|
||||
export default defineConfig({
|
||||
integrations: [solid()],
|
||||
});
|
12
packages/astro/e2e/fixtures/solid-component/package.json
Normal file
12
packages/astro/e2e/fixtures/solid-component/package.json
Normal file
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"name": "@e2e/solid-component",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@astrojs/solid-js": "workspace:*",
|
||||
"astro": "workspace:*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"solid-js": "^1.4.1"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
.counter {
|
||||
display: grid;
|
||||
font-size: 2em;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
margin-top: 3em;
|
||||
place-items: center;
|
||||
}
|
||||
|
||||
.counter-message {
|
||||
text-align: center;
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
import { createSignal } from 'solid-js';
|
||||
import './Counter.css';
|
||||
|
||||
export default function Counter({ children, id, count: initialCount = 0 }) {
|
||||
const [count, setCount] = createSignal(initialCount);
|
||||
const add = () => setCount(count() + 1);
|
||||
const subtract = () => setCount(count() - 1);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div id={id} class="counter">
|
||||
<button class="decrement" onClick={subtract}>-</button>
|
||||
<pre>{count()}</pre>
|
||||
<button class="increment" onClick={add}>+</button>
|
||||
</div>
|
||||
<div class="counter-message">{children}</div>
|
||||
</>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
---
|
||||
import Counter from '../components/Counter.jsx';
|
||||
|
||||
const someProps = {
|
||||
count: 0,
|
||||
};
|
||||
---
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<!-- Head Stuff -->
|
||||
</head>
|
||||
<body>
|
||||
<Counter id="server-only" {...someProps}>
|
||||
<h1>Hello, server!</h1>
|
||||
</Counter>
|
||||
|
||||
<Counter id="client-idle" {...someProps} client:idle>
|
||||
<h1>Hello, client:idle!</h1>
|
||||
</Counter>
|
||||
|
||||
<Counter id="client-load" {...someProps} client:load>
|
||||
<h1>Hello, client:load!</h1>
|
||||
</Counter>
|
||||
|
||||
<Counter id="client-visible" {...someProps} client:visible>
|
||||
<h1>Hello, client:visible!</h1>
|
||||
</Counter>
|
||||
|
||||
<Counter id="client-media" {...someProps} client:media="(max-width: 50em)">
|
||||
<h1>Hello, client:media!</h1>
|
||||
</Counter>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,7 @@
|
|||
import { defineConfig } from 'astro/config';
|
||||
import svelte from '@astrojs/svelte';
|
||||
|
||||
// https://astro.build/config
|
||||
export default defineConfig({
|
||||
integrations: [svelte()],
|
||||
});
|
10
packages/astro/e2e/fixtures/svelte-component/package.json
Normal file
10
packages/astro/e2e/fixtures/svelte-component/package.json
Normal file
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"name": "@e2e/svelte-component",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@astrojs/svelte": "workspace:*",
|
||||
"astro": "workspace:*",
|
||||
"svelte": "^3.48.0"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
<script lang="ts">
|
||||
export let id: string;
|
||||
|
||||
let count = 0;
|
||||
|
||||
function add() {
|
||||
count += 1;
|
||||
}
|
||||
|
||||
function subtract() {
|
||||
count -= 1;
|
||||
}
|
||||
</script>
|
||||
|
||||
<div {id} class="counter">
|
||||
<button class="decrement" on:click={subtract}>-</button>
|
||||
<pre>{ count }</pre>
|
||||
<button class="increment" on:click={add}>+</button>
|
||||
</div>
|
||||
<div id={`${id}-message`} class="message">
|
||||
<slot />
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.counter{
|
||||
display: grid;
|
||||
font-size: 2em;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
margin-top: 2em;
|
||||
place-items: center;
|
||||
}
|
||||
.message {
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,34 @@
|
|||
---
|
||||
import Counter from '../components/Counter.svelte';
|
||||
|
||||
const someProps = {
|
||||
count: 0,
|
||||
};
|
||||
---
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<!-- Head Stuff -->
|
||||
</head>
|
||||
<body>
|
||||
<Counter id="server-only">
|
||||
<h1>Hello, server!</h1>
|
||||
</Counter>
|
||||
|
||||
<Counter id="client-idle" client:idle>
|
||||
<h1>Hello, client:idle!</h1>
|
||||
</Counter>
|
||||
|
||||
<Counter id="client-load" client:load>
|
||||
<h1>Hello, client:load!</h1>
|
||||
</Counter>
|
||||
|
||||
<Counter id="client-visible" client:visible>
|
||||
<h1>Hello, client:visible!</h1>
|
||||
</Counter>
|
||||
|
||||
<Counter id="client-media" client:media="(max-width: 50rem)">
|
||||
<h1>Hello, client:media!</h1>
|
||||
</Counter>
|
||||
</body>
|
||||
</html>
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "@test/e2e-tailwindcss",
|
||||
"name": "@e2e/e2e-tailwindcss",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
|
|
13
packages/astro/e2e/fixtures/vue-component/astro.config.mjs
Normal file
13
packages/astro/e2e/fixtures/vue-component/astro.config.mjs
Normal file
|
@ -0,0 +1,13 @@
|
|||
import { defineConfig } from 'astro/config';
|
||||
import vue from '@astrojs/vue';
|
||||
|
||||
// https://astro.build/config
|
||||
export default defineConfig({
|
||||
integrations: [vue({
|
||||
template: {
|
||||
compilerOptions: {
|
||||
isCustomElement: tag => tag.includes('my-button')
|
||||
}
|
||||
}
|
||||
})],
|
||||
});
|
9
packages/astro/e2e/fixtures/vue-component/package.json
Normal file
9
packages/astro/e2e/fixtures/vue-component/package.json
Normal file
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"name": "@test/vue-component",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@astrojs/vue": "workspace:*",
|
||||
"astro": "workspace:*"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
<template>
|
||||
<div :id="id" class="counter">
|
||||
<h1><slot /></h1>
|
||||
<button class="decrement" @click="subtract()">-</button>
|
||||
<Result :value="count" />
|
||||
<button class="increment" @click="add()">+</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref } from 'vue';
|
||||
|
||||
import Result from './Result.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Result
|
||||
},
|
||||
props: {
|
||||
id: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
start: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
stepSize: {
|
||||
type: String,
|
||||
default: "1"
|
||||
}
|
||||
},
|
||||
setup(props) {
|
||||
const id = props.id;
|
||||
const count = ref(parseInt(props.start))
|
||||
const stepSize = ref(parseInt(props.stepSize))
|
||||
const add = () => (count.value = count.value + stepSize.value);
|
||||
const subtract = () => (count.value = count.value - stepSize.value);
|
||||
return {
|
||||
count,
|
||||
id,
|
||||
add,
|
||||
subtract,
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
|
@ -0,0 +1,16 @@
|
|||
<template>
|
||||
<pre>{{ value }}</pre>
|
||||
<my-button>Click Me</my-button>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
props: {
|
||||
value: {
|
||||
type: Number,
|
||||
required: true
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,33 @@
|
|||
---
|
||||
import Counter from '../components/Counter.vue'
|
||||
---
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width"
|
||||
/>
|
||||
<title>Vue component</title>
|
||||
<style>
|
||||
:global(:root) {
|
||||
font-family: system-ui;
|
||||
padding: 1em;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<Counter id="server-only" start="0">No Client</Counter>
|
||||
<Counter id="client-load" start="0" client:load>Hello, client:load!</Counter>
|
||||
<!-- Test island deduplication, i.e. same UID as the component above. -->
|
||||
<Counter id="client-load-dup" start="0" client:load>Hello, client:load!</Counter>
|
||||
<!-- Test island deduplication account for non-render affecting props. -->
|
||||
<Counter id="client-load-step" start="0" step-size="2" client:load>Hello, client:load!</Counter>
|
||||
<Counter id="client-idle" start="0" client:idle>Hello, client:idle!</Counter>
|
||||
<!-- Test that two client:visibles have unique uids -->
|
||||
<Counter id="client-visible" start="0" client:visible>Hello, client:visible!</Counter>
|
||||
<Counter id="client-media" start="0" client:media="(max-width: 50rem)">Hello, client:media!</Counter>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
103
packages/astro/e2e/lit-component.test.js
Normal file
103
packages/astro/e2e/lit-component.test.js
Normal file
|
@ -0,0 +1,103 @@
|
|||
import { test as base, expect } from '@playwright/test';
|
||||
import { loadFixture } from './test-utils.js';
|
||||
|
||||
const test = base.extend({
|
||||
astro: async ({}, use) => {
|
||||
const fixture = await loadFixture({ root: './fixtures/lit-component/' });
|
||||
await use(fixture);
|
||||
},
|
||||
});
|
||||
|
||||
let devServer;
|
||||
|
||||
test.beforeEach(async ({ astro }) => {
|
||||
devServer = await astro.startDevServer();
|
||||
});
|
||||
|
||||
test.afterEach(async () => {
|
||||
await devServer.stop();
|
||||
});
|
||||
|
||||
// TODO: configure playwright to handle web component APIs
|
||||
// https://github.com/microsoft/playwright/issues/14241
|
||||
test.describe.skip('Lit components', () => {
|
||||
test('client:idle', async ({ page, astro }) => {
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
const counter = page.locator('#client-idle');
|
||||
await expect(counter, 'component is visible').toBeVisible();
|
||||
|
||||
const count = counter.locator('p');
|
||||
await expect(count, 'initial count is 0').toHaveText('Count: 0');
|
||||
|
||||
const inc = counter.locator('button');
|
||||
await inc.click();
|
||||
|
||||
await expect(count, 'count incremented by 1').toHaveText('Count: 1');
|
||||
});
|
||||
|
||||
test('client:load', async ({ page, astro }) => {
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
const counter = page.locator('#client-load');
|
||||
await expect(counter, 'component is visible').toBeVisible();
|
||||
|
||||
const count = counter.locator('p');
|
||||
await expect(count, 'initial count is 0').toHaveText('Count: 0');
|
||||
|
||||
const inc = counter.locator('button');
|
||||
await inc.click();
|
||||
|
||||
await expect(count, 'count incremented by 1').toHaveText('Count: 1');
|
||||
});
|
||||
|
||||
test('client:visible', async ({ page, astro }) => {
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
// Make sure the component is on screen to trigger hydration
|
||||
const counter = page.locator('#client-visible');
|
||||
await counter.scrollIntoViewIfNeeded();
|
||||
await expect(counter, 'component is visible').toBeVisible();
|
||||
|
||||
const count = counter.locator('p');
|
||||
await expect(count, 'initial count is 0').toHaveText('Count: 0');
|
||||
|
||||
const inc = counter.locator('button');
|
||||
await inc.click();
|
||||
|
||||
await expect(count, 'count incremented by 1').toHaveText('Count: 1');
|
||||
});
|
||||
|
||||
test('client:media', async ({ page, astro }) => {
|
||||
await page.goto(astro.resolveUrl('/media'));
|
||||
|
||||
const counter = page.locator('#client-media');
|
||||
await expect(counter, 'component is visible').toBeVisible();
|
||||
|
||||
const count = counter.locator('p');
|
||||
await expect(count, 'initial count is 0').toHaveText('Count: 0');
|
||||
|
||||
const inc = counter.locator('button');
|
||||
await inc.click();
|
||||
|
||||
await expect(count, 'component not hydrated yet').toHaveText('Count: 0');
|
||||
|
||||
// Reset the viewport to hydrate the component (max-width: 50rem)
|
||||
await page.setViewportSize({ width: 414, height: 1124 });
|
||||
|
||||
await inc.click();
|
||||
await expect(count, 'count incremented by 1').toHaveText('Count: 1');
|
||||
});
|
||||
|
||||
test('HMR', async ({ page, astro }) => {
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
const label = page.locator('#client-idle h1');
|
||||
|
||||
await astro.editFile('./src/pages/index.astro', (original) =>
|
||||
original.replace('Hello, client:idle!', 'Hello, updated client:idle!')
|
||||
);
|
||||
|
||||
await expect(label, 'slot text updated').toHaveText('Hello, updated client:idle!');
|
||||
});
|
||||
});
|
141
packages/astro/e2e/multiple-frameworks.test.js
Normal file
141
packages/astro/e2e/multiple-frameworks.test.js
Normal file
|
@ -0,0 +1,141 @@
|
|||
import { test as base, expect } from '@playwright/test';
|
||||
import { loadFixture } from './test-utils.js';
|
||||
|
||||
const test = base.extend({
|
||||
astro: async ({}, use) => {
|
||||
const fixture = await loadFixture({ root: './fixtures/multiple-frameworks/' });
|
||||
await use(fixture);
|
||||
},
|
||||
});
|
||||
|
||||
let devServer;
|
||||
|
||||
test.beforeEach(async ({ astro }) => {
|
||||
devServer = await astro.startDevServer();
|
||||
});
|
||||
|
||||
test.afterEach(async () => {
|
||||
await devServer.stop();
|
||||
});
|
||||
|
||||
test.describe('Multiple frameworks', () => {
|
||||
test('React counter', async ({ astro, page }) => {
|
||||
await page.goto('/');
|
||||
|
||||
const counter = await page.locator('#react-counter');
|
||||
await expect(counter, 'component is visible').toBeVisible();
|
||||
|
||||
const count = await counter.locator('pre');
|
||||
await expect(count, 'initial count is 0').toHaveText('0');
|
||||
|
||||
const increment = await counter.locator('.increment');
|
||||
await increment.click();
|
||||
|
||||
await expect(count, 'count incremented by 1').toHaveText('1');
|
||||
});
|
||||
|
||||
test('Preact counter', async ({ astro, page }) => {
|
||||
await page.goto('/');
|
||||
|
||||
const counter = await page.locator('#preact-counter');
|
||||
await expect(counter, 'component is visible').toBeVisible();
|
||||
|
||||
const count = await counter.locator('pre');
|
||||
await expect(count, 'initial count is 0').toHaveText('0');
|
||||
|
||||
const increment = await counter.locator('.increment');
|
||||
await increment.click();
|
||||
|
||||
await expect(count, 'count incremented by 1').toHaveText('1');
|
||||
});
|
||||
|
||||
test('Solid counter', async ({ astro, page }) => {
|
||||
await page.goto('/');
|
||||
|
||||
const counter = await page.locator('#solid-counter');
|
||||
await expect(counter, 'component is visible').toBeVisible();
|
||||
|
||||
const count = await counter.locator('pre');
|
||||
await expect(count, 'initial count is 0').toHaveText('0');
|
||||
|
||||
const increment = await counter.locator('.increment');
|
||||
await increment.click();
|
||||
|
||||
await expect(count, 'count incremented by 1').toHaveText('1');
|
||||
});
|
||||
|
||||
test('Vue counter', async ({ astro, page }) => {
|
||||
await page.goto('/');
|
||||
|
||||
const counter = await page.locator('#vue-counter');
|
||||
await expect(counter, 'component is visible').toBeVisible();
|
||||
|
||||
const count = await counter.locator('pre');
|
||||
await expect(count, 'initial count is 0').toHaveText('0');
|
||||
|
||||
const increment = await counter.locator('.increment');
|
||||
await increment.click();
|
||||
|
||||
await expect(count, 'count incremented by 1').toHaveText('1');
|
||||
});
|
||||
|
||||
test('Svelte counter', async ({ astro, page }) => {
|
||||
await page.goto('/');
|
||||
|
||||
const counter = await page.locator('#svelte-counter');
|
||||
await expect(counter, 'component is visible').toBeVisible();
|
||||
|
||||
const count = await counter.locator('pre');
|
||||
await expect(count, 'initial count is 0').toHaveText('0');
|
||||
|
||||
const increment = await counter.locator('.increment');
|
||||
await increment.click();
|
||||
|
||||
await expect(count, 'count incremented by 1').toHaveText('1');
|
||||
});
|
||||
|
||||
test('Astro components', async ({ astro, page }) => {
|
||||
await page.goto('/');
|
||||
|
||||
const aComponent = await page.locator('#astro-a');
|
||||
await expect(aComponent, 'component is visible').toBeVisible();
|
||||
await expect(aComponent, 'component text is visible').toHaveText('Hello Astro (A)');
|
||||
|
||||
|
||||
const bComponent = await page.locator('#astro-b');
|
||||
await expect(bComponent, 'component is visible').toBeVisible();
|
||||
await expect(bComponent, 'component text is visible').toHaveText('Hello Astro (B)');
|
||||
});
|
||||
|
||||
test('HMR', async ({ astro, page }) => {
|
||||
await page.goto('/');
|
||||
|
||||
// 1: updating the page template
|
||||
const preactSlot = page.locator('#preact-counter + .counter-message');
|
||||
await expect(preactSlot, 'initial slot content').toHaveText('Hello Preact!');
|
||||
|
||||
await astro.editFile('./src/pages/index.astro', (content) =>
|
||||
content.replace('Hello Preact!', 'Hello Preact, updated!')
|
||||
);
|
||||
|
||||
await expect(preactSlot, 'slot content updated').toHaveText('Hello Preact, updated!');
|
||||
|
||||
// Edit the react component
|
||||
await astro.editFile('./src/components/ReactCounter.jsx', (content) =>
|
||||
content.replace('useState(0)', 'useState(5)')
|
||||
);
|
||||
|
||||
const reactCount = await page.locator('#react-counter pre');
|
||||
await expect(reactCount, 'initial count updated to 5').toHaveText('5');
|
||||
|
||||
// Edit the svelte component's style
|
||||
const svelteCounter = page.locator('#svelte-counter');
|
||||
await expect(svelteCounter, 'initial background is white').toHaveCSS('background-color', 'rgb(255, 255, 255)');
|
||||
|
||||
await astro.editFile('./src/components/SvelteCounter.svelte', (content) =>
|
||||
content.replace('background: white', 'background: rgb(230, 230, 230)')
|
||||
);
|
||||
|
||||
await expect(svelteCounter, 'background color updated').toHaveCSS('background-color', 'rgb(230, 230, 230)');
|
||||
});
|
||||
});
|
|
@ -10,18 +10,18 @@ const test = base.extend({
|
|||
|
||||
let devServer;
|
||||
|
||||
test.beforeAll(async ({ astro }) => {
|
||||
test.beforeEach(async ({ astro }) => {
|
||||
devServer = await astro.startDevServer();
|
||||
});
|
||||
|
||||
test.afterAll(async ({ astro }) => {
|
||||
test.afterEach(async () => {
|
||||
await devServer.stop();
|
||||
});
|
||||
|
||||
test('Loading styles that are nested', async ({ page, astro }) => {
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
test.describe('Loading styles that are nested', () => {
|
||||
test('header', async ({ page, astro }) => {
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
await test.step('header', async () => {
|
||||
const header = page.locator('header');
|
||||
|
||||
await expect(header, 'should have background color').toHaveCSS(
|
||||
|
|
143
packages/astro/e2e/preact-component.test.js
Normal file
143
packages/astro/e2e/preact-component.test.js
Normal file
|
@ -0,0 +1,143 @@
|
|||
import { test as base, expect } from '@playwright/test';
|
||||
import { loadFixture } from './test-utils.js';
|
||||
|
||||
const test = base.extend({
|
||||
astro: async ({}, use) => {
|
||||
const fixture = await loadFixture({ root: './fixtures/preact-component/' });
|
||||
await use(fixture);
|
||||
},
|
||||
});
|
||||
|
||||
let devServer;
|
||||
|
||||
test.beforeEach(async ({ astro }) => {
|
||||
devServer = await astro.startDevServer();
|
||||
});
|
||||
|
||||
test.afterEach(async () => {
|
||||
await devServer.stop();
|
||||
});
|
||||
|
||||
test.describe('Preact components', () => {
|
||||
test('server only', async ({ page, astro }) => {
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
const counter = page.locator('#server-only');
|
||||
await expect(counter, 'component is visible').toBeVisible();
|
||||
|
||||
const count = counter.locator('pre');
|
||||
await expect(count, 'initial count is 0').toHaveText('0');
|
||||
|
||||
const inc = counter.locator('.increment');
|
||||
await inc.click();
|
||||
|
||||
await expect(count, 'count incremented by 1').toHaveText('0');
|
||||
});
|
||||
|
||||
test('client:idle', async ({ page, astro }) => {
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
const counter = page.locator('#client-idle');
|
||||
await expect(counter, 'component is visible').toBeVisible();
|
||||
|
||||
const count = counter.locator('pre');
|
||||
await expect(count, 'initial count is 0').toHaveText('0');
|
||||
|
||||
const inc = counter.locator('.increment');
|
||||
await inc.click();
|
||||
|
||||
await expect(count, 'count incremented by 1').toHaveText('1');
|
||||
});
|
||||
|
||||
test('client:load', async ({ page, astro }) => {
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
const counter = page.locator('#client-load');
|
||||
await expect(counter, 'component is visible').toBeVisible();
|
||||
|
||||
const count = counter.locator('pre');
|
||||
await expect(count, 'initial count is 0').toHaveText('0');
|
||||
|
||||
const inc = counter.locator('.increment');
|
||||
await inc.click();
|
||||
|
||||
await expect(count, 'count incremented by 1').toHaveText('1');
|
||||
});
|
||||
|
||||
test('client:visible', async ({ page, astro }) => {
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
// Make sure the component is on screen to trigger hydration
|
||||
const counter = page.locator('#client-visible');
|
||||
await counter.scrollIntoViewIfNeeded();
|
||||
await expect(counter, 'component is visible').toBeVisible();
|
||||
|
||||
const count = counter.locator('pre');
|
||||
await expect(count, 'initial count is 0').toHaveText('0');
|
||||
|
||||
const inc = counter.locator('.increment');
|
||||
await inc.click();
|
||||
|
||||
await expect(count, 'count incremented by 1').toHaveText('1');
|
||||
});
|
||||
|
||||
test('client:media', async ({ page, astro }) => {
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
const counter = page.locator('#client-media');
|
||||
await expect(counter, 'component is visible').toBeVisible();
|
||||
|
||||
const count = counter.locator('pre');
|
||||
await expect(count, 'initial count is 0').toHaveText('0');
|
||||
|
||||
const inc = counter.locator('.increment');
|
||||
await inc.click();
|
||||
await expect(count, 'component not hydrated yet').toHaveText('0');
|
||||
|
||||
// Reset the viewport to hydrate the component (max-width: 50rem)
|
||||
await page.setViewportSize({ width: 414, height: 1124 });
|
||||
await inc.click();
|
||||
await expect(count, 'count incremented by 1').toHaveText('1');
|
||||
});
|
||||
|
||||
test('client:only', async ({ page, astro }) => {
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
const label = page.locator('#client-only');
|
||||
await expect(label, 'component is visible').toBeVisible();
|
||||
|
||||
await expect(label, 'slot text is visible').toHaveText('Preact client:only component');
|
||||
});
|
||||
|
||||
test('HMR', async ({ page, astro }) => {
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
const count = page.locator('#client-idle pre');
|
||||
await expect(count, 'initial count is 0').toHaveText('0');
|
||||
|
||||
// Edit the component's initial count prop
|
||||
await astro.editFile('./src/pages/index.astro', (original) =>
|
||||
original.replace('id="client-idle" {...someProps}', 'id="client-idle" count={5}')
|
||||
);
|
||||
|
||||
await expect(count, 'count prop updated').toHaveText('5');
|
||||
|
||||
// Edit the component's slot text
|
||||
await astro.editFile('./src/components/JSXComponent.jsx', (original) =>
|
||||
original.replace('Preact client:only component', 'Updated preact client:only component')
|
||||
);
|
||||
|
||||
const label = page.locator('#client-only');
|
||||
await expect(label, 'client:only component is visible').toBeVisible();
|
||||
await expect(label, 'client:only slot text is visible').toHaveText(
|
||||
'Updated preact client:only component'
|
||||
);
|
||||
|
||||
// Edit the imported CSS file
|
||||
await astro.editFile('./src/components/Counter.css', (original) =>
|
||||
original.replace('font-size: 2em;', 'font-size: 24px;')
|
||||
);
|
||||
|
||||
await expect(count, 'imported styles updated').toHaveCSS('font-size', '24px');
|
||||
});
|
||||
});
|
143
packages/astro/e2e/react-component.test.js
Normal file
143
packages/astro/e2e/react-component.test.js
Normal file
|
@ -0,0 +1,143 @@
|
|||
import { test as base, expect } from '@playwright/test';
|
||||
import { loadFixture } from './test-utils.js';
|
||||
|
||||
const test = base.extend({
|
||||
astro: async ({}, use) => {
|
||||
const fixture = await loadFixture({ root: './fixtures/react-component/' });
|
||||
await use(fixture);
|
||||
},
|
||||
});
|
||||
|
||||
let devServer;
|
||||
|
||||
test.beforeEach(async ({ astro }) => {
|
||||
devServer = await astro.startDevServer();
|
||||
});
|
||||
|
||||
test.afterEach(async () => {
|
||||
await devServer.stop();
|
||||
});
|
||||
|
||||
test.describe('React components', () => {
|
||||
test('server only', async ({ page, astro }) => {
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
const counter = page.locator('#server-only');
|
||||
await expect(counter, 'component is visible').toBeVisible();
|
||||
|
||||
const count = counter.locator('pre');
|
||||
await expect(count, 'initial count is 0').toHaveText('0');
|
||||
|
||||
const inc = counter.locator('.increment');
|
||||
await inc.click();
|
||||
|
||||
await expect(count, 'component not hydrated').toHaveText('0');
|
||||
});
|
||||
|
||||
test('client:idle', async ({ page, astro }) => {
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
const counter = page.locator('#client-idle');
|
||||
await expect(counter, 'component is visible').toBeVisible();
|
||||
|
||||
const count = counter.locator('pre');
|
||||
await expect(count, 'initial count is 0').toHaveText('0');
|
||||
|
||||
const inc = counter.locator('.increment');
|
||||
await inc.click();
|
||||
|
||||
await expect(count, 'count incremented by 1').toHaveText('1');
|
||||
});
|
||||
|
||||
test('client:load', async ({ page, astro }) => {
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
const counter = page.locator('#client-load');
|
||||
await expect(counter, 'component is visible').toBeVisible();
|
||||
|
||||
const count = counter.locator('pre');
|
||||
await expect(count, 'initial count is 0').toHaveText('0');
|
||||
|
||||
const inc = counter.locator('.increment');
|
||||
await inc.click();
|
||||
|
||||
await expect(count, 'count incremented by 1').toHaveText('1');
|
||||
});
|
||||
|
||||
test('client:visible', async ({ page, astro }) => {
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
// Make sure the component is on screen to trigger hydration
|
||||
const counter = page.locator('#client-visible');
|
||||
await counter.scrollIntoViewIfNeeded();
|
||||
await expect(counter, 'component is visible').toBeVisible();
|
||||
|
||||
const count = counter.locator('pre');
|
||||
await expect(count, 'initial count is 0').toHaveText('0');
|
||||
|
||||
const inc = counter.locator('.increment');
|
||||
await inc.click();
|
||||
|
||||
await expect(count, 'count incremented by 1').toHaveText('1');
|
||||
});
|
||||
|
||||
test('client:media', async ({ page, astro }) => {
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
const counter = page.locator('#client-media');
|
||||
await expect(counter, 'component is visible').toBeVisible();
|
||||
|
||||
const count = counter.locator('pre');
|
||||
await expect(count, 'initial count is 0').toHaveText('0');
|
||||
|
||||
const inc = counter.locator('.increment');
|
||||
await inc.click();
|
||||
await expect(count, 'component not hydrated yet').toHaveText('0');
|
||||
|
||||
// Reset the viewport to hydrate the component (max-width: 50rem)
|
||||
await page.setViewportSize({ width: 414, height: 1124 });
|
||||
await inc.click();
|
||||
await expect(count, 'count incremented by 1').toHaveText('1');
|
||||
});
|
||||
|
||||
test('client:only', async ({ page, astro }) => {
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
const label = page.locator('#client-only');
|
||||
await expect(label, 'component is visible').toBeVisible();
|
||||
|
||||
await expect(label, 'slot text is visible').toHaveText('React client:only component');
|
||||
});
|
||||
|
||||
test('HMR', async ({ page, astro }) => {
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
const count = page.locator('#client-idle pre');
|
||||
await expect(count, 'initial count is 0').toHaveText('0');
|
||||
|
||||
// Edit the component's initial count prop
|
||||
await astro.editFile('./src/pages/index.astro', (original) =>
|
||||
original.replace('id="client-idle" {...someProps}', 'id="client-idle" count={5}')
|
||||
);
|
||||
|
||||
await expect(count, 'count prop updated').toHaveText('5');
|
||||
|
||||
// Edit the component's slot text
|
||||
await astro.editFile('./src/components/JSXComponent.jsx', (original) =>
|
||||
original.replace('React client:only component', 'Updated react client:only component')
|
||||
);
|
||||
|
||||
const label = page.locator('#client-only');
|
||||
await expect(label, 'client:only component is visible').toBeVisible();
|
||||
await expect(label, 'client:only slot text is visible').toHaveText(
|
||||
'Updated react client:only component'
|
||||
);
|
||||
|
||||
// Edit the imported CSS file
|
||||
await astro.editFile('./src/components/Counter.css', (original) =>
|
||||
original.replace('font-size: 2em;', 'font-size: 24px;')
|
||||
);
|
||||
|
||||
await expect(count, 'imported CSS updated').toHaveCSS('font-size', '24px');
|
||||
});
|
||||
});
|
123
packages/astro/e2e/solid-component.test.js
Normal file
123
packages/astro/e2e/solid-component.test.js
Normal file
|
@ -0,0 +1,123 @@
|
|||
import { test as base, expect } from '@playwright/test';
|
||||
import { loadFixture } from './test-utils.js';
|
||||
|
||||
const test = base.extend({
|
||||
astro: async ({}, use) => {
|
||||
const fixture = await loadFixture({ root: './fixtures/solid-component/' });
|
||||
await use(fixture);
|
||||
},
|
||||
});
|
||||
|
||||
let devServer;
|
||||
|
||||
test.beforeEach(async ({ astro }) => {
|
||||
devServer = await astro.startDevServer();
|
||||
});
|
||||
|
||||
test.afterEach(async () => {
|
||||
await devServer.stop();
|
||||
});
|
||||
|
||||
test.describe('Solid components', () => {
|
||||
test('server only', async ({ page, astro }) => {
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
const counter = page.locator('#server-only');
|
||||
await expect(counter, 'component is visible').toBeVisible();
|
||||
|
||||
const count = counter.locator('pre');
|
||||
await expect(count, 'initial count is 0').toHaveText('0');
|
||||
|
||||
const inc = counter.locator('.increment');
|
||||
await inc.click();
|
||||
|
||||
await expect(count, 'component not hydrated').toHaveText('0');
|
||||
});
|
||||
|
||||
test('client:idle', async ({ page, astro }) => {
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
const counter = page.locator('#client-idle');
|
||||
await expect(counter, 'component is visible').toBeVisible();
|
||||
|
||||
const count = counter.locator('pre');
|
||||
await expect(count, 'initial count is 0').toHaveText('0');
|
||||
|
||||
const inc = counter.locator('.increment');
|
||||
await inc.click();
|
||||
|
||||
await expect(count, 'count incremented by 1').toHaveText('1');
|
||||
});
|
||||
|
||||
test('client:load', async ({ page, astro }) => {
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
const counter = page.locator('#client-load');
|
||||
await expect(counter, 'component is visible').toBeVisible();
|
||||
|
||||
const count = counter.locator('pre');
|
||||
await expect(count, 'initial count is 0').toHaveText('0');
|
||||
|
||||
const inc = counter.locator('.increment');
|
||||
await inc.click();
|
||||
|
||||
await expect(count, 'count incremented by 1').toHaveText('1');
|
||||
});
|
||||
|
||||
test('client:visible', async ({ page, astro }) => {
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
// Make sure the component is on screen to trigger hydration
|
||||
const counter = page.locator('#client-visible');
|
||||
await counter.scrollIntoViewIfNeeded();
|
||||
await expect(counter, 'component is visible').toBeVisible();
|
||||
|
||||
const count = counter.locator('pre');
|
||||
await expect(count, 'initial count is 0').toHaveText('0');
|
||||
|
||||
const inc = counter.locator('.increment');
|
||||
await inc.click();
|
||||
|
||||
await expect(count, 'count incremented by 1').toHaveText('1');
|
||||
});
|
||||
|
||||
test('client:media', async ({ page, astro }) => {
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
const counter = page.locator('#client-media');
|
||||
await expect(counter, 'component is visible').toBeVisible();
|
||||
|
||||
const count = counter.locator('pre');
|
||||
await expect(count, 'initial count is 0').toHaveText('0');
|
||||
|
||||
const inc = counter.locator('.increment');
|
||||
await inc.click();
|
||||
await expect(count, 'component not hydrated yet').toHaveText('0');
|
||||
|
||||
// Reset the viewport to hydrate the component (max-width: 50rem)
|
||||
await page.setViewportSize({ width: 414, height: 1124 });
|
||||
await inc.click();
|
||||
await expect(count, 'count incremented by 1').toHaveText('1');
|
||||
});
|
||||
|
||||
test('HMR', async ({ page, astro }) => {
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
const count = page.locator('#client-idle pre');
|
||||
await expect(count, 'initial count is 0').toHaveText('0');
|
||||
|
||||
// Edit the component's initial count prop
|
||||
await astro.editFile('./src/pages/index.astro', (original) =>
|
||||
original.replace('id="client-idle" {...someProps}', 'id="client-idle" count={5}')
|
||||
);
|
||||
|
||||
await expect(count, 'count prop updated').toHaveText('5');
|
||||
|
||||
// Edit the imported CSS
|
||||
await astro.editFile('./src/components/Counter.css', (original) =>
|
||||
original.replace('font-size: 2em;', 'font-size: 24px;')
|
||||
);
|
||||
|
||||
await expect(count, 'imported CSS updated').toHaveCSS('font-size', '24px');
|
||||
});
|
||||
});
|
114
packages/astro/e2e/svelte-component.test.js
Normal file
114
packages/astro/e2e/svelte-component.test.js
Normal file
|
@ -0,0 +1,114 @@
|
|||
import { test as base, expect } from '@playwright/test';
|
||||
import { loadFixture } from './test-utils.js';
|
||||
|
||||
const test = base.extend({
|
||||
astro: async ({}, use) => {
|
||||
const fixture = await loadFixture({ root: './fixtures/svelte-component/' });
|
||||
await use(fixture);
|
||||
},
|
||||
});
|
||||
|
||||
let devServer;
|
||||
|
||||
test.beforeEach(async ({ astro }) => {
|
||||
devServer = await astro.startDevServer();
|
||||
});
|
||||
|
||||
test.afterEach(async () => {
|
||||
await devServer.stop();
|
||||
});
|
||||
|
||||
test.describe('Svelte components', () => {
|
||||
test('server only', async ({ page, astro }) => {
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
const counter = page.locator('#server-only');
|
||||
await expect(counter, 'component is visible').toBeVisible();
|
||||
|
||||
const count = counter.locator('pre');
|
||||
await expect(count, 'initial count is 0').toHaveText('0');
|
||||
|
||||
const inc = counter.locator('.increment');
|
||||
await inc.click();
|
||||
|
||||
await expect(count, 'component not hydrated').toHaveText('0');
|
||||
});
|
||||
|
||||
test('client:idle', async ({ page, astro }) => {
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
const counter = page.locator('#client-idle');
|
||||
await expect(counter, 'component is visible').toBeVisible();
|
||||
|
||||
const count = counter.locator('pre');
|
||||
await expect(count, 'initial count is 0').toHaveText('0');
|
||||
|
||||
const inc = counter.locator('.increment');
|
||||
await inc.click();
|
||||
|
||||
await expect(count, 'count incremented by 1').toHaveText('1');
|
||||
});
|
||||
|
||||
test('client:load', async ({ page, astro }) => {
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
const counter = page.locator('#client-load');
|
||||
await expect(counter, 'component is visible').toBeVisible();
|
||||
|
||||
const count = counter.locator('pre');
|
||||
await expect(count, 'initial count is 0').toHaveText('0');
|
||||
|
||||
const inc = counter.locator('.increment');
|
||||
await inc.click();
|
||||
|
||||
await expect(count, 'count incremented by 1').toHaveText('1');
|
||||
});
|
||||
|
||||
test('client:visible', async ({ page, astro }) => {
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
// Make sure the component is on screen to trigger hydration
|
||||
const counter = page.locator('#client-visible');
|
||||
await counter.scrollIntoViewIfNeeded();
|
||||
await expect(counter, 'component is visible').toBeVisible();
|
||||
|
||||
const count = counter.locator('pre');
|
||||
await expect(count, 'initial count is 0').toHaveText('0');
|
||||
|
||||
const inc = counter.locator('.increment');
|
||||
await inc.click();
|
||||
|
||||
await expect(count, 'count incremented by 1').toHaveText('1');
|
||||
});
|
||||
|
||||
test('client:media', async ({ page, astro }) => {
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
const counter = page.locator('#client-media');
|
||||
await expect(counter, 'component is visible').toBeVisible();
|
||||
|
||||
const count = counter.locator('pre');
|
||||
await expect(count, 'initial count is 0').toHaveText('0');
|
||||
|
||||
const inc = counter.locator('.increment');
|
||||
await inc.click();
|
||||
await expect(count, 'component not hydrated yet').toHaveText('0');
|
||||
|
||||
// Reset the viewport to hydrate the component (max-width: 50rem)
|
||||
await page.setViewportSize({ width: 414, height: 1124 });
|
||||
await inc.click();
|
||||
await expect(count, 'count incremented by 1').toHaveText('1');
|
||||
});
|
||||
|
||||
test('HMR', async ({ page, astro }) => {
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
// Edit the component's slot text
|
||||
await astro.editFile('./src/pages/index.astro', (original) =>
|
||||
original.replace('Hello, client:idle!', 'Hello, updated client:idle!')
|
||||
);
|
||||
|
||||
const label = page.locator('#client-idle-message');
|
||||
await expect(label, 'slot text updated').toHaveText('Hello, updated client:idle!');
|
||||
});
|
||||
});
|
|
@ -10,18 +10,19 @@ const test = base.extend({
|
|||
|
||||
let devServer;
|
||||
|
||||
test.beforeAll(async ({ astro }) => {
|
||||
test.beforeEach(async ({ astro }) => {
|
||||
devServer = await astro.startDevServer();
|
||||
});
|
||||
|
||||
test.afterAll(async ({ astro }) => {
|
||||
test.afterEach(async ({ astro }) => {
|
||||
await devServer.stop();
|
||||
astro.resetAllFiles();
|
||||
});
|
||||
|
||||
test('Tailwind CSS', async ({ page, astro }) => {
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
test.describe('Tailwind CSS', () => {
|
||||
test('body', async ({ page, astro }) => {
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
await test.step('body', async () => {
|
||||
const body = page.locator('body');
|
||||
|
||||
await expect(body, 'should have classes').toHaveClass('bg-dawn text-midnight');
|
||||
|
@ -32,7 +33,9 @@ test('Tailwind CSS', async ({ page, astro }) => {
|
|||
await expect(body, 'should have color').toHaveCSS('color', 'rgb(49, 39, 74)');
|
||||
});
|
||||
|
||||
await test.step('button', async () => {
|
||||
test('button', async ({ page, astro }) => {
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
const button = page.locator('button');
|
||||
|
||||
await expect(button, 'should have bg-purple-600').toHaveClass(/bg-purple-600/);
|
||||
|
@ -48,4 +51,20 @@ test('Tailwind CSS', async ({ page, astro }) => {
|
|||
await expect(button, 'should have font-[900]').toHaveClass(/font-\[900\]/);
|
||||
await expect(button, 'should have font weight').toHaveCSS('font-weight', '900');
|
||||
});
|
||||
|
||||
test('HMR', async ({ page, astro }) => {
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
await astro.editFile('./src/components/Button.astro', (original) =>
|
||||
original.replace('bg-purple-600', 'bg-purple-400')
|
||||
);
|
||||
|
||||
const button = page.locator('button');
|
||||
|
||||
await expect(button, 'should have bg-purple-400').toHaveClass(/bg-purple-400/);
|
||||
await expect(button, 'should have background color').toHaveCSS(
|
||||
'background-color',
|
||||
'rgb(192, 132, 252)'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
144
packages/astro/e2e/vue-component.test.js
Normal file
144
packages/astro/e2e/vue-component.test.js
Normal file
|
@ -0,0 +1,144 @@
|
|||
import { test as base, expect } from '@playwright/test';
|
||||
import { loadFixture } from './test-utils.js';
|
||||
|
||||
const test = base.extend({
|
||||
astro: async ({}, use) => {
|
||||
const fixture = await loadFixture({ root: './fixtures/vue-component/' });
|
||||
await use(fixture);
|
||||
},
|
||||
});
|
||||
|
||||
let devServer;
|
||||
|
||||
test.beforeEach(async ({ astro }) => {
|
||||
devServer = await astro.startDevServer();
|
||||
});
|
||||
|
||||
test.afterEach(async () => {
|
||||
await devServer.stop();
|
||||
});
|
||||
|
||||
test.describe('Vue components', () => {
|
||||
test('server only', async ({ page, astro }) => {
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
const counter = page.locator('#server-only');
|
||||
await expect(counter, 'component is visible').toBeVisible();
|
||||
|
||||
const count = counter.locator('pre');
|
||||
await expect(count, 'initial count is 0').toHaveText('0');
|
||||
|
||||
const inc = counter.locator('.increment');
|
||||
await inc.click();
|
||||
|
||||
await expect(count, 'component not hydrated').toHaveText('0');
|
||||
});
|
||||
|
||||
test('client:idle', async ({ page, astro }) => {
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
const counter = page.locator('#client-idle');
|
||||
await expect(counter, 'component is visible').toBeVisible();
|
||||
|
||||
const count = counter.locator('pre');
|
||||
await expect(count, 'initial count is 0').toHaveText('0');
|
||||
|
||||
const inc = counter.locator('.increment');
|
||||
await inc.click();
|
||||
|
||||
await expect(count, 'count incremented by 1').toHaveText('1');
|
||||
});
|
||||
|
||||
test('client:load', async ({ page, astro }) => {
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
// Multiple counters on the page to verify islands aren't sharing state
|
||||
const counter = page.locator('#client-load');
|
||||
const counterDup = page.locator('#client-load-dup');
|
||||
const counterStep = page.locator('#client-load-step');
|
||||
|
||||
await expect(counter).toBeVisible();
|
||||
await expect(counterDup).toBeVisible();
|
||||
await expect(counterStep).toBeVisible();
|
||||
|
||||
const count = counter.locator('pre');
|
||||
const countDup = counterDup.locator('pre');
|
||||
const countStep = counterStep.locator('pre');
|
||||
|
||||
const countInc = counter.locator('.increment');
|
||||
const countDupInc = counterDup.locator('.increment');
|
||||
const countStepInc = counterStep.locator('.increment');
|
||||
|
||||
// Should only increment the first counter
|
||||
await countInc.click();
|
||||
|
||||
await expect(count, 'intial count is 1').toHaveText('1');
|
||||
await expect(countDup, 'initial count is 0').toHaveText('0');
|
||||
await expect(countStep, 'initial count is 0').toHaveText('0');
|
||||
|
||||
// Should only increment the second counter
|
||||
await countDupInc.click();
|
||||
|
||||
await expect(count, "count didn't change").toHaveText('1');
|
||||
await expect(countDup, 'count incremented by 1').toHaveText('1');
|
||||
await expect(countStep, "count didn't change").toHaveText('0');
|
||||
|
||||
// Should only increment the third counter
|
||||
// Expecting an increase of 4 becasuse the component's
|
||||
// step is set to 2
|
||||
await countStepInc.click();
|
||||
await countStepInc.click();
|
||||
|
||||
await expect(count, "count didn't change").toHaveText('1');
|
||||
await expect(countDup, "count didn't change").toHaveText('1');
|
||||
await expect(countStep, 'count incremented by 4').toHaveText('4');
|
||||
});
|
||||
|
||||
test('client:visible', async ({ page, astro }) => {
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
// Make sure the component is on screen to trigger hydration
|
||||
const counter = page.locator('#client-visible');
|
||||
await counter.scrollIntoViewIfNeeded();
|
||||
await expect(counter).toBeVisible();
|
||||
|
||||
const count = counter.locator('pre');
|
||||
await expect(count, 'initial count is 0').toHaveText('0');
|
||||
|
||||
const inc = counter.locator('.increment');
|
||||
await inc.click();
|
||||
|
||||
await expect(count, 'count incremented by 1').toHaveText('1');
|
||||
});
|
||||
|
||||
test('client:media', async ({ page, astro }) => {
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
const counter = page.locator('#client-media');
|
||||
await expect(counter, 'component is visible').toBeVisible();
|
||||
|
||||
const count = counter.locator('pre');
|
||||
await expect(count, 'initial count is 0').toHaveText('0');
|
||||
|
||||
const inc = counter.locator('.increment');
|
||||
await inc.click();
|
||||
await expect(count, 'component not hydrated yet').toHaveText('0');
|
||||
|
||||
// Reset the viewport to hydrate the component (max-width: 50rem)
|
||||
await page.setViewportSize({ width: 414, height: 1124 });
|
||||
await inc.click();
|
||||
await expect(count, 'count incremented by 1').toHaveText('1');
|
||||
});
|
||||
|
||||
test('HMR', async ({ page, astro }) => {
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
// Edit the component's slot text
|
||||
await astro.editFile('./src/pages/index.astro', (original) =>
|
||||
original.replace('Hello, client:visible!', 'Hello, updated client:visible!')
|
||||
);
|
||||
|
||||
const label = page.locator('#client-visible h1');
|
||||
await expect(label, 'slotted text updated').toHaveText('Hello, updated client:visible!');
|
||||
});
|
||||
});
|
|
@ -73,7 +73,8 @@
|
|||
"benchmark": "node test/benchmark/dev.bench.js && node test/benchmark/build.bench.js",
|
||||
"test": "mocha --exit --timeout 20000 --ignore **/lit-element.test.js --ignore **/errors.test.js && mocha --timeout 20000 **/lit-element.test.js && mocha --timeout 20000 **/errors.test.js",
|
||||
"test:match": "mocha --timeout 20000 -g",
|
||||
"test:e2e": "playwright test e2e"
|
||||
"test:e2e": "playwright test",
|
||||
"test:e2e:match": "playwright test -g"
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/compiler": "^0.14.3",
|
||||
|
|
42
packages/astro/playwright.config.js
Normal file
42
packages/astro/playwright.config.js
Normal file
|
@ -0,0 +1,42 @@
|
|||
import { devices } from '@playwright/test';
|
||||
|
||||
const config = {
|
||||
testMatch: 'e2e/*.test.js',
|
||||
/* Maximum time one test can run for. */
|
||||
timeout: 30 * 1000,
|
||||
expect: {
|
||||
/**
|
||||
* Maximum time expect() should wait for the condition to be met.
|
||||
* For example in `await expect(locator).toHaveText();`
|
||||
*/
|
||||
timeout: 5000
|
||||
},
|
||||
/* Fail the build on CI if you accidentally left test in the source code. */
|
||||
forbidOnly: !!process.env.CI,
|
||||
/* Retry on CI only */
|
||||
retries: process.env.CI ? 2 : 0,
|
||||
/* Opt out of parallel tests on CI. */
|
||||
workers: process.env.CI ? 1 : undefined,
|
||||
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
|
||||
use: {
|
||||
/* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */
|
||||
actionTimeout: 0,
|
||||
/* Base URL to use in actions like `await page.goto('/')`. */
|
||||
baseURL: process.env.PLAYWRIGHT_TEST_BASE_URL || 'http://localhost:3000',
|
||||
|
||||
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
|
||||
trace: 'on-first-retry',
|
||||
},
|
||||
projects: [
|
||||
{
|
||||
name: 'Chrome Stable',
|
||||
use: {
|
||||
browserName: 'chromium',
|
||||
channel: 'chrome',
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
};
|
||||
|
||||
export default config;
|
|
@ -31,7 +31,7 @@ if (import.meta.hot) {
|
|||
}
|
||||
}
|
||||
if (hasAstroUpdate) {
|
||||
return updatePage();
|
||||
return await updatePage();
|
||||
}
|
||||
}
|
||||
import.meta.hot.on('vite:beforeUpdate', async (event) => {
|
||||
|
|
|
@ -52,9 +52,7 @@ describe('Error display', () => {
|
|||
expect($('.statusMessage').text()).to.equal('Internal Error');
|
||||
|
||||
// 2. Edit the file, fixing the error
|
||||
let changeOccured = fixture.onNextChange();
|
||||
await fixture.editFile('./src/components/SvelteSyntaxError.svelte', `<h1>No mismatch</h1>`);
|
||||
await changeOccured;
|
||||
|
||||
// 3. Verify that the file is fixed.
|
||||
html = await fixture.fetch('/svelte-syntax-error').then((res) => res.text());
|
||||
|
|
|
@ -28,6 +28,7 @@ polyfill(globalThis, {
|
|||
* @property {(url: string) => string} resolveUrl
|
||||
* @property {(url: string, opts: any) => Promise<Response>} fetch
|
||||
* @property {(path: string) => Promise<string>} readFile
|
||||
* @property {(path: string, updater: (content: string) => string) => Promise<void>} writeFile
|
||||
* @property {(path: string) => Promise<string[]>} readdir
|
||||
* @property {() => Promise<DevServer>} startDevServer
|
||||
* @property {() => Promise<PreviewServer>} preview
|
||||
|
@ -97,7 +98,7 @@ export async function loadFixture(inlineConfig) {
|
|||
|
||||
const resolveUrl = (url) =>
|
||||
`http://${'127.0.0.1'}:${config.server.port}${url.replace(/^\/?/, '/')}`;
|
||||
|
||||
|
||||
// A map of files that have been editted.
|
||||
let fileEdits = new Map();
|
||||
|
||||
|
@ -108,6 +109,11 @@ export async function loadFixture(inlineConfig) {
|
|||
fileEdits.clear();
|
||||
};
|
||||
|
||||
const onNextChange = () =>
|
||||
devServer
|
||||
? new Promise((resolve) => devServer.watcher.once('change', resolve))
|
||||
: Promise.reject(new Error('No dev server running'))
|
||||
|
||||
// After each test, reset each of the edits to their original contents.
|
||||
if (typeof afterEach === 'function') {
|
||||
afterEach(resetAllFiles);
|
||||
|
@ -134,7 +140,9 @@ export async function loadFixture(inlineConfig) {
|
|||
readFile: (filePath) =>
|
||||
fs.promises.readFile(new URL(filePath.replace(/^\//, ''), config.outDir), 'utf8'),
|
||||
readdir: (fp) => fs.promises.readdir(new URL(fp.replace(/^\//, ''), config.outDir)),
|
||||
clean: () => fs.promises.rm(config.outDir, { maxRetries: 10, recursive: true, force: true }),
|
||||
clean: async () => {
|
||||
await fs.promises.rm(config.outDir, { maxRetries: 10, recursive: true, force: true });
|
||||
},
|
||||
loadTestAdapterApp: async () => {
|
||||
const url = new URL('./server/entry.mjs', config.outDir);
|
||||
const { createApp, manifest } = await import(url);
|
||||
|
@ -142,22 +150,26 @@ export async function loadFixture(inlineConfig) {
|
|||
app.manifest = manifest;
|
||||
return app;
|
||||
},
|
||||
editFile: async (filePath, newContents) => {
|
||||
editFile: async (filePath, newContentsOrCallback) => {
|
||||
const fileUrl = new URL(filePath.replace(/^\//, ''), config.root);
|
||||
const contents = await fs.promises.readFile(fileUrl, 'utf-8');
|
||||
const reset = () => fs.writeFileSync(fileUrl, contents);
|
||||
const reset = () => {
|
||||
fs.writeFileSync(fileUrl, contents);
|
||||
}
|
||||
// Only save this reset if not already in the map, in case multiple edits happen
|
||||
// to the same file.
|
||||
if (!fileEdits.has(fileUrl.toString())) {
|
||||
fileEdits.set(fileUrl.toString(), reset);
|
||||
}
|
||||
const newContents = typeof newContentsOrCallback === 'function'
|
||||
? newContentsOrCallback(contents)
|
||||
: newContentsOrCallback;
|
||||
const nextChange = onNextChange();
|
||||
await fs.promises.writeFile(fileUrl, newContents);
|
||||
await nextChange;
|
||||
return reset;
|
||||
},
|
||||
onNextChange: () =>
|
||||
devServer
|
||||
? new Promise((resolve) => devServer.watcher.once('change', resolve))
|
||||
: Promise.reject(new Error('No dev server running')),
|
||||
resetAllFiles
|
||||
};
|
||||
}
|
||||
|
||||
|
|
282
pnpm-lock.yaml
282
pnpm-lock.yaml
|
@ -661,12 +661,108 @@ importers:
|
|||
chai-as-promised: 7.1.1_chai@4.3.6
|
||||
mocha: 9.2.2
|
||||
|
||||
packages/astro/e2e/fixtures/astro-component:
|
||||
specifiers:
|
||||
astro: workspace:*
|
||||
dependencies:
|
||||
astro: link:../../..
|
||||
|
||||
packages/astro/e2e/fixtures/lit-component:
|
||||
specifiers:
|
||||
'@astrojs/lit': workspace:*
|
||||
'@webcomponents/template-shadowroot': ^0.1.0
|
||||
astro: workspace:*
|
||||
lit: ^2.2.3
|
||||
dependencies:
|
||||
'@astrojs/lit': link:../../../../integrations/lit
|
||||
'@webcomponents/template-shadowroot': 0.1.0
|
||||
astro: link:../../..
|
||||
lit: 2.2.4
|
||||
|
||||
packages/astro/e2e/fixtures/multiple-frameworks:
|
||||
specifiers:
|
||||
'@astrojs/lit': ^0.1.3
|
||||
'@astrojs/preact': ^0.1.2
|
||||
'@astrojs/react': ^0.1.2
|
||||
'@astrojs/solid-js': ^0.1.2
|
||||
'@astrojs/svelte': ^0.1.3
|
||||
'@astrojs/vue': ^0.1.4
|
||||
'@webcomponents/template-shadowroot': ^0.1.0
|
||||
astro: ^1.0.0-beta.31
|
||||
lit: ^2.2.4
|
||||
preact: ^10.7.2
|
||||
react: ^18.1.0
|
||||
react-dom: ^18.1.0
|
||||
solid-js: ^1.4.2
|
||||
svelte: ^3.48.0
|
||||
vue: ^3.2.34
|
||||
dependencies:
|
||||
'@webcomponents/template-shadowroot': 0.1.0
|
||||
lit: 2.2.4
|
||||
preact: 10.7.2
|
||||
react: 18.1.0
|
||||
react-dom: 18.1.0_react@18.1.0
|
||||
solid-js: 1.4.2
|
||||
svelte: 3.48.0
|
||||
vue: 3.2.34
|
||||
devDependencies:
|
||||
'@astrojs/lit': link:../../../../integrations/lit
|
||||
'@astrojs/preact': link:../../../../integrations/preact
|
||||
'@astrojs/react': link:../../../../integrations/react
|
||||
'@astrojs/solid-js': link:../../../../integrations/solid
|
||||
'@astrojs/svelte': link:../../../../integrations/svelte
|
||||
'@astrojs/vue': link:../../../../integrations/vue
|
||||
astro: link:../../..
|
||||
|
||||
packages/astro/e2e/fixtures/nested-styles:
|
||||
specifiers:
|
||||
astro: workspace:*
|
||||
dependencies:
|
||||
astro: link:../../..
|
||||
|
||||
packages/astro/e2e/fixtures/preact-component:
|
||||
specifiers:
|
||||
'@astrojs/preact': workspace:*
|
||||
astro: workspace:*
|
||||
preact: ^10.7.2
|
||||
dependencies:
|
||||
'@astrojs/preact': link:../../../../integrations/preact
|
||||
astro: link:../../..
|
||||
preact: 10.7.2
|
||||
|
||||
packages/astro/e2e/fixtures/react-component:
|
||||
specifiers:
|
||||
'@astrojs/react': workspace:*
|
||||
astro: workspace:*
|
||||
react: ^18.1.0
|
||||
react-dom: ^18.1.0
|
||||
dependencies:
|
||||
'@astrojs/react': link:../../../../integrations/react
|
||||
astro: link:../../..
|
||||
react: 18.1.0
|
||||
react-dom: 18.1.0_react@18.1.0
|
||||
|
||||
packages/astro/e2e/fixtures/solid-component:
|
||||
specifiers:
|
||||
'@astrojs/solid-js': workspace:*
|
||||
astro: workspace:*
|
||||
solid-js: ^1.4.1
|
||||
dependencies:
|
||||
'@astrojs/solid-js': link:../../../../integrations/solid
|
||||
astro: link:../../..
|
||||
devDependencies:
|
||||
solid-js: 1.4.2
|
||||
|
||||
packages/astro/e2e/fixtures/svelte-component:
|
||||
specifiers:
|
||||
'@astrojs/svelte': workspace:*
|
||||
astro: workspace:*
|
||||
svelte: ^3.48.0
|
||||
dependencies:
|
||||
'@astrojs/svelte': link:../../../../integrations/svelte
|
||||
astro: link:../../..
|
||||
svelte: 3.48.0
|
||||
|
||||
packages/astro/e2e/fixtures/tailwindcss:
|
||||
specifiers:
|
||||
'@astrojs/tailwind': workspace:*
|
||||
|
@ -675,6 +771,14 @@ importers:
|
|||
'@astrojs/tailwind': link:../../../../integrations/tailwind
|
||||
astro: link:../../..
|
||||
|
||||
packages/astro/e2e/fixtures/vue-component:
|
||||
specifiers:
|
||||
'@astrojs/vue': workspace:*
|
||||
astro: workspace:*
|
||||
dependencies:
|
||||
'@astrojs/vue': link:../../../../integrations/vue
|
||||
astro: link:../../..
|
||||
|
||||
packages/astro/test/fixtures/0-css:
|
||||
specifiers:
|
||||
'@astrojs/react': workspace:*
|
||||
|
@ -1972,7 +2076,7 @@ packages:
|
|||
resolution: {integrity: sha512-rgi3g078uAxdb8jg1A5U8sNWMUQq7UXwHT7qmPiGOeB+h5p+tzUFy/Awq2suv99Tq8efpn3HrAGTuDvxyvbwfg==}
|
||||
dependencies:
|
||||
svelte: 3.48.0
|
||||
svelte2tsx: 0.5.10_wwvk7nlptlrqo2czohjtk6eiqm
|
||||
svelte2tsx: 0.5.9_wwvk7nlptlrqo2czohjtk6eiqm
|
||||
transitivePeerDependencies:
|
||||
- typescript
|
||||
dev: false
|
||||
|
@ -3725,7 +3829,7 @@ packages:
|
|||
dependencies:
|
||||
'@lit-labs/ssr-client': 1.0.1
|
||||
'@lit/reactive-element': 1.3.2
|
||||
'@types/node': 16.11.36
|
||||
'@types/node': 16.11.34
|
||||
lit: 2.2.4
|
||||
lit-element: 3.2.0
|
||||
lit-html: 2.2.4
|
||||
|
@ -3748,7 +3852,7 @@ packages:
|
|||
resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==}
|
||||
dependencies:
|
||||
'@babel/runtime': 7.18.0
|
||||
'@types/node': 12.20.52
|
||||
'@types/node': 12.20.51
|
||||
find-up: 4.1.0
|
||||
fs-extra: 8.1.0
|
||||
dev: true
|
||||
|
@ -6032,7 +6136,7 @@ packages:
|
|||
slash: 3.0.0
|
||||
dev: true
|
||||
|
||||
/@rollup/plugin-babel/5.3.1_ykg7cmcqpmn5fbkb5gxs7i3du4:
|
||||
/@rollup/plugin-babel/5.3.1_3gvlzenj6qraw2ojvkgevxalie:
|
||||
resolution: {integrity: sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==}
|
||||
engines: {node: '>= 10.0.0'}
|
||||
peerDependencies:
|
||||
|
@ -6047,8 +6151,8 @@ packages:
|
|||
dependencies:
|
||||
'@babel/core': 7.18.0
|
||||
'@babel/helper-module-imports': 7.16.7
|
||||
'@rollup/pluginutils': 3.1.0_rollup@2.74.1
|
||||
rollup: 2.74.1
|
||||
'@rollup/pluginutils': 3.1.0_rollup@2.72.1
|
||||
rollup: 2.72.1
|
||||
dev: true
|
||||
|
||||
/@rollup/plugin-inject/4.0.4_rollup@2.74.1:
|
||||
|
@ -6062,19 +6166,19 @@ packages:
|
|||
rollup: 2.74.1
|
||||
dev: true
|
||||
|
||||
/@rollup/plugin-node-resolve/11.2.1_rollup@2.74.1:
|
||||
/@rollup/plugin-node-resolve/11.2.1_rollup@2.72.1:
|
||||
resolution: {integrity: sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg==}
|
||||
engines: {node: '>= 10.0.0'}
|
||||
peerDependencies:
|
||||
rollup: ^1.20.0||^2.0.0
|
||||
dependencies:
|
||||
'@rollup/pluginutils': 3.1.0_rollup@2.74.1
|
||||
'@rollup/pluginutils': 3.1.0_rollup@2.72.1
|
||||
'@types/resolve': 1.17.1
|
||||
builtin-modules: 3.3.0
|
||||
deepmerge: 4.2.2
|
||||
is-module: 1.0.0
|
||||
resolve: 1.22.0
|
||||
rollup: 2.74.1
|
||||
rollup: 2.72.1
|
||||
dev: true
|
||||
|
||||
/@rollup/plugin-node-resolve/13.3.0_rollup@2.74.1:
|
||||
|
@ -6092,14 +6196,14 @@ packages:
|
|||
rollup: 2.74.1
|
||||
dev: true
|
||||
|
||||
/@rollup/plugin-replace/2.4.2_rollup@2.74.1:
|
||||
/@rollup/plugin-replace/2.4.2_rollup@2.72.1:
|
||||
resolution: {integrity: sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==}
|
||||
peerDependencies:
|
||||
rollup: ^1.20.0 || ^2.0.0
|
||||
dependencies:
|
||||
'@rollup/pluginutils': 3.1.0_rollup@2.74.1
|
||||
'@rollup/pluginutils': 3.1.0_rollup@2.72.1
|
||||
magic-string: 0.25.9
|
||||
rollup: 2.74.1
|
||||
rollup: 2.72.1
|
||||
dev: true
|
||||
|
||||
/@rollup/plugin-typescript/8.3.2_ewnwotriipvq7wps276zlnnxuy:
|
||||
|
@ -6117,6 +6221,18 @@ packages:
|
|||
typescript: 4.6.4
|
||||
dev: true
|
||||
|
||||
/@rollup/pluginutils/3.1.0_rollup@2.72.1:
|
||||
resolution: {integrity: sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==}
|
||||
engines: {node: '>= 8.0.0'}
|
||||
peerDependencies:
|
||||
rollup: ^1.20.0||^2.0.0
|
||||
dependencies:
|
||||
'@types/estree': 0.0.39
|
||||
estree-walker: 1.0.1
|
||||
picomatch: 2.3.1
|
||||
rollup: 2.72.1
|
||||
dev: true
|
||||
|
||||
/@rollup/pluginutils/3.1.0_rollup@2.74.1:
|
||||
resolution: {integrity: sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==}
|
||||
engines: {node: '>= 8.0.0'}
|
||||
|
@ -6255,7 +6371,7 @@ packages:
|
|||
/@types/connect/3.4.35:
|
||||
resolution: {integrity: sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==}
|
||||
dependencies:
|
||||
'@types/node': 17.0.35
|
||||
'@types/node': 17.0.32
|
||||
dev: true
|
||||
|
||||
/@types/debug/4.1.7:
|
||||
|
@ -6296,7 +6412,7 @@ packages:
|
|||
resolution: {integrity: sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==}
|
||||
dependencies:
|
||||
'@types/minimatch': 3.0.5
|
||||
'@types/node': 17.0.35
|
||||
'@types/node': 17.0.32
|
||||
dev: true
|
||||
|
||||
/@types/hast/2.3.4:
|
||||
|
@ -6360,20 +6476,20 @@ packages:
|
|||
'@types/unist': 2.0.6
|
||||
dev: false
|
||||
|
||||
/@types/node/12.20.52:
|
||||
resolution: {integrity: sha512-cfkwWw72849SNYp3Zx0IcIs25vABmFh73xicxhCkTcvtZQeIez15PpwQN8fY3RD7gv1Wrxlc9MEtfMORZDEsGw==}
|
||||
/@types/node/12.20.51:
|
||||
resolution: {integrity: sha512-anVDMfReTatfH8GVmHmaTZOL0jeTLNZ9wK9SSrQS3tMmn4vUc+9fVWlUzAieuQefWDyWUz4Z3aqXxDgO1VsYjg==}
|
||||
dev: true
|
||||
|
||||
/@types/node/14.18.18:
|
||||
resolution: {integrity: sha512-B9EoJFjhqcQ9OmQrNorItO+OwEOORNn3S31WuiHvZY/dm9ajkB7AKD/8toessEtHHNL+58jofbq7hMMY9v4yig==}
|
||||
dev: true
|
||||
|
||||
/@types/node/16.11.36:
|
||||
resolution: {integrity: sha512-FR5QJe+TaoZ2GsMHkjuwoNabr+UrJNRr2HNOo+r/7vhcuntM6Ee/pRPOnRhhL2XE9OOvX9VLEq+BcXl3VjNoWA==}
|
||||
/@types/node/16.11.34:
|
||||
resolution: {integrity: sha512-UrWGDyLAlQ2Z8bNOGWTsqbP9ZcBeTYBVuTRNxXTztBy5KhWUFI3BaeDWoCP/CzV/EVGgO1NTYzv9ZytBI9GAEw==}
|
||||
dev: false
|
||||
|
||||
/@types/node/17.0.35:
|
||||
resolution: {integrity: sha512-vu1SrqBjbbZ3J6vwY17jBs8Sr/BKA+/a/WtjRG+whKg1iuLFOosq872EXS0eXWILdO36DHQQeku/ZcL6hz2fpg==}
|
||||
/@types/node/17.0.32:
|
||||
resolution: {integrity: sha512-eAIcfAvhf/BkHcf4pkLJ7ECpBAhh9kcxRBpip9cTiO+hf+aJrsxYxBeS6OXvOd9WqNAJmavXVpZvY1rBjNsXmw==}
|
||||
|
||||
/@types/normalize-package-data/2.4.1:
|
||||
resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==}
|
||||
|
@ -6397,7 +6513,7 @@ packages:
|
|||
/@types/prompts/2.0.14:
|
||||
resolution: {integrity: sha512-HZBd99fKxRWpYCErtm2/yxUZv6/PBI9J7N4TNFffl5JbrYMHBwF25DjQGTW3b3jmXq+9P6/8fCIb2ee57BFfYA==}
|
||||
dependencies:
|
||||
'@types/node': 17.0.35
|
||||
'@types/node': 17.0.32
|
||||
dev: false
|
||||
|
||||
/@types/prop-types/15.7.5:
|
||||
|
@ -6437,7 +6553,7 @@ packages:
|
|||
/@types/resolve/1.17.1:
|
||||
resolution: {integrity: sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==}
|
||||
dependencies:
|
||||
'@types/node': 14.18.18
|
||||
'@types/node': 17.0.32
|
||||
dev: true
|
||||
|
||||
/@types/resolve/1.20.2:
|
||||
|
@ -6447,19 +6563,19 @@ packages:
|
|||
resolution: {integrity: sha512-F3OznnSLAUxFrCEu/L5PY8+ny8DtcFRjx7fZZ9bycvXRi3KPTRS9HOitGZwvPg0juRhXFWIeKX58cnX5YqLohQ==}
|
||||
dependencies:
|
||||
'@types/glob': 7.2.0
|
||||
'@types/node': 17.0.35
|
||||
'@types/node': 17.0.32
|
||||
dev: true
|
||||
|
||||
/@types/sass/1.43.1:
|
||||
resolution: {integrity: sha512-BPdoIt1lfJ6B7rw35ncdwBZrAssjcwzI5LByIrYs+tpXlj/CAkuVdRsgZDdP4lq5EjyWzwxZCqAoFyHKFwp32g==}
|
||||
dependencies:
|
||||
'@types/node': 17.0.35
|
||||
'@types/node': 17.0.32
|
||||
dev: false
|
||||
|
||||
/@types/sax/1.2.4:
|
||||
resolution: {integrity: sha512-pSAff4IAxJjfAXUG6tFkO7dsSbTmf8CtUpfhhZ5VhkRpC4628tJhh3+V6H1E+/Gs9piSzYKT5yzHO5M4GG9jkw==}
|
||||
dependencies:
|
||||
'@types/node': 17.0.35
|
||||
'@types/node': 17.0.32
|
||||
dev: false
|
||||
|
||||
/@types/scheduler/0.16.2:
|
||||
|
@ -6473,7 +6589,7 @@ packages:
|
|||
resolution: {integrity: sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q==}
|
||||
dependencies:
|
||||
'@types/mime': 1.3.2
|
||||
'@types/node': 17.0.35
|
||||
'@types/node': 17.0.32
|
||||
dev: true
|
||||
|
||||
/@types/tailwindcss/3.0.10:
|
||||
|
@ -6726,7 +6842,7 @@ packages:
|
|||
acorn: 8.7.1
|
||||
bindings: 1.5.0
|
||||
estree-walker: 2.0.2
|
||||
glob: 7.2.3
|
||||
glob: 7.2.0
|
||||
graceful-fs: 4.2.10
|
||||
micromatch: 4.0.5
|
||||
node-gyp-build: 4.4.0
|
||||
|
@ -6974,13 +7090,8 @@ packages:
|
|||
engines: {node: '>=6'}
|
||||
dev: true
|
||||
|
||||
/ansi-colors/4.1.3:
|
||||
resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==}
|
||||
engines: {node: '>=6'}
|
||||
dev: true
|
||||
|
||||
/ansi-regex/2.1.1:
|
||||
resolution: {integrity: sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==}
|
||||
resolution: {integrity: sha1-w7M6te42DYbg5ijwRorn7yfWVN8=}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
/ansi-regex/5.0.1:
|
||||
|
@ -7064,7 +7175,7 @@ packages:
|
|||
dev: false
|
||||
|
||||
/arrify/1.0.1:
|
||||
resolution: {integrity: sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==}
|
||||
resolution: {integrity: sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=}
|
||||
engines: {node: '>=0.10.0'}
|
||||
dev: true
|
||||
|
||||
|
@ -7112,7 +7223,7 @@ packages:
|
|||
postcss: ^8.1.0
|
||||
dependencies:
|
||||
browserslist: 4.20.3
|
||||
caniuse-lite: 1.0.30001341
|
||||
caniuse-lite: 1.0.30001340
|
||||
fraction.js: 4.2.0
|
||||
normalize-range: 0.1.2
|
||||
picocolors: 1.0.0
|
||||
|
@ -7244,7 +7355,7 @@ packages:
|
|||
dev: false
|
||||
|
||||
/boolbase/1.0.0:
|
||||
resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==}
|
||||
resolution: {integrity: sha1-aN/1++YMUes3cl6p4+0xDcwed24=}
|
||||
|
||||
/boxen/6.2.1:
|
||||
resolution: {integrity: sha512-H4PEsJXfFI/Pt8sjDWbHlQPx4zL/bvSQjcilJmaulGt5mLDorHOHpmdXAJcBcmru7PhYSp/cDMWRko4ZUMFkSw==}
|
||||
|
@ -7293,14 +7404,14 @@ packages:
|
|||
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
caniuse-lite: 1.0.30001341
|
||||
caniuse-lite: 1.0.30001340
|
||||
electron-to-chromium: 1.4.137
|
||||
escalade: 3.1.1
|
||||
node-releases: 2.0.4
|
||||
picocolors: 1.0.0
|
||||
|
||||
/buffer-crc32/0.2.13:
|
||||
resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==}
|
||||
resolution: {integrity: sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=}
|
||||
dev: false
|
||||
|
||||
/buffer-from/1.1.2:
|
||||
|
@ -7369,8 +7480,8 @@ packages:
|
|||
resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
/caniuse-lite/1.0.30001341:
|
||||
resolution: {integrity: sha512-2SodVrFFtvGENGCv0ChVJIDQ0KPaS1cg7/qtfMaICgeMolDdo/Z2OD32F0Aq9yl6F4YFwGPBS5AaPqNYiW4PoA==}
|
||||
/caniuse-lite/1.0.30001340:
|
||||
resolution: {integrity: sha512-jUNz+a9blQTQVu4uFcn17uAD8IDizPzQkIKh3LCJfg9BkyIqExYYdyc/ZSlWUSKb8iYiXxKsxbv4zYSvkqjrxw==}
|
||||
|
||||
/canvas-confetti/1.5.1:
|
||||
resolution: {integrity: sha512-Ncz+oZJP6OvY7ti4E1slxVlyAV/3g7H7oQtcCDXgwGgARxPnwYY9PW5Oe+I8uvspYNtuHviAdgA0LfcKFWJfpg==}
|
||||
|
@ -7451,7 +7562,7 @@ packages:
|
|||
dev: true
|
||||
|
||||
/check-error/1.0.2:
|
||||
resolution: {integrity: sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==}
|
||||
resolution: {integrity: sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=}
|
||||
dev: true
|
||||
|
||||
/cheerio-select/1.6.0:
|
||||
|
@ -8037,7 +8148,7 @@ packages:
|
|||
resolution: {integrity: sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==}
|
||||
engines: {node: '>=8.6'}
|
||||
dependencies:
|
||||
ansi-colors: 4.1.3
|
||||
ansi-colors: 4.1.1
|
||||
dev: true
|
||||
|
||||
/entities/2.2.0:
|
||||
|
@ -8682,10 +8793,8 @@ packages:
|
|||
resolution: {integrity: sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==}
|
||||
dev: true
|
||||
|
||||
/for-each/0.3.3:
|
||||
resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==}
|
||||
dependencies:
|
||||
is-callable: 1.2.4
|
||||
/foreach/2.0.6:
|
||||
resolution: {integrity: sha512-k6GAGDyqLe9JaebCsFCoudPPWfihKu8pylYXRlqP1J7ms39iPoTtk2fviNglIeQEwdh0bQeKJ01ZPyuyQvKzwg==}
|
||||
dev: false
|
||||
|
||||
/formdata-polyfill/4.0.10:
|
||||
|
@ -8883,17 +8992,6 @@ packages:
|
|||
minimatch: 3.1.2
|
||||
once: 1.4.0
|
||||
path-is-absolute: 1.0.1
|
||||
dev: true
|
||||
|
||||
/glob/7.2.3:
|
||||
resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
|
||||
dependencies:
|
||||
fs.realpath: 1.0.0
|
||||
inflight: 1.0.6
|
||||
inherits: 2.0.4
|
||||
minimatch: 3.1.2
|
||||
once: 1.4.0
|
||||
path-is-absolute: 1.0.1
|
||||
|
||||
/globals/11.12.0:
|
||||
resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==}
|
||||
|
@ -9563,14 +9661,14 @@ packages:
|
|||
dependencies:
|
||||
has-symbols: 1.0.3
|
||||
|
||||
/is-typed-array/1.1.9:
|
||||
resolution: {integrity: sha512-kfrlnTTn8pZkfpJMUgYD7YZ3qzeJgWUn8XfVYBARc4wnmNOmLbmuuaAs3q5fvB0UJOn6yHAKaGTPM7d6ezoD/A==}
|
||||
/is-typed-array/1.1.8:
|
||||
resolution: {integrity: sha512-HqH41TNZq2fgtGT8WHVFVJhBVGuY3AnP3Q36K8JKXUxSxRgk/d+7NjmwG2vo2mYmXK8UYZKu0qH8bVP5gEisjA==}
|
||||
engines: {node: '>= 0.4'}
|
||||
dependencies:
|
||||
available-typed-arrays: 1.0.5
|
||||
call-bind: 1.0.2
|
||||
es-abstract: 1.20.1
|
||||
for-each: 0.3.3
|
||||
foreach: 2.0.6
|
||||
has-tostringtag: 1.0.0
|
||||
dev: false
|
||||
|
||||
|
@ -9625,7 +9723,7 @@ packages:
|
|||
resolution: {integrity: sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==}
|
||||
engines: {node: '>= 10.13.0'}
|
||||
dependencies:
|
||||
'@types/node': 17.0.35
|
||||
'@types/node': 17.0.32
|
||||
merge-stream: 2.0.0
|
||||
supports-color: 7.2.0
|
||||
dev: true
|
||||
|
@ -11711,13 +11809,25 @@ packages:
|
|||
resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
glob: 7.2.3
|
||||
glob: 7.2.0
|
||||
|
||||
/rimraf/3.0.2:
|
||||
resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
glob: 7.2.3
|
||||
glob: 7.2.0
|
||||
|
||||
/rollup-plugin-terser/7.0.2_rollup@2.72.1:
|
||||
resolution: {integrity: sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==}
|
||||
peerDependencies:
|
||||
rollup: ^2.0.0
|
||||
dependencies:
|
||||
'@babel/code-frame': 7.16.7
|
||||
jest-worker: 26.6.2
|
||||
rollup: 2.72.1
|
||||
serialize-javascript: 4.0.0
|
||||
terser: 5.13.1
|
||||
dev: true
|
||||
|
||||
/rollup-plugin-terser/7.0.2_rollup@2.74.1:
|
||||
resolution: {integrity: sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==}
|
||||
|
@ -11737,6 +11847,14 @@ packages:
|
|||
estree-walker: 0.6.1
|
||||
dev: false
|
||||
|
||||
/rollup/2.72.1:
|
||||
resolution: {integrity: sha512-NTc5UGy/NWFGpSqF1lFY8z9Adri6uhyMLI6LvPAXdBKoPRFhIIiBUpt+Qg2awixqO3xvzSijjhnb4+QEZwJmxA==}
|
||||
engines: {node: '>=10.0.0'}
|
||||
hasBin: true
|
||||
optionalDependencies:
|
||||
fsevents: 2.3.2
|
||||
dev: true
|
||||
|
||||
/rollup/2.74.1:
|
||||
resolution: {integrity: sha512-K2zW7kV8Voua5eGkbnBtWYfMIhYhT9Pel2uhBk2WO5eMee161nPze/XRfvEQPFYz7KgrCCnmh2Wy0AMFLGGmMA==}
|
||||
engines: {node: '>=10.0.0'}
|
||||
|
@ -11955,7 +12073,7 @@ packages:
|
|||
engines: {node: '>=12.0.0', npm: '>=5.6.0'}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
'@types/node': 17.0.35
|
||||
'@types/node': 17.0.32
|
||||
'@types/sax': 1.2.4
|
||||
arg: 5.0.1
|
||||
sax: 1.2.4
|
||||
|
@ -12012,6 +12130,10 @@ packages:
|
|||
smart-buffer: 4.2.0
|
||||
dev: true
|
||||
|
||||
/solid-js/1.3.17:
|
||||
resolution: {integrity: sha512-BFCosxa4hRm+LF7S+kBL5bNr4RtuZif6AaR5FdQkBpV1E6QNLAOFm4HWgEN8vL2aCWEKl384cT8Etw8ziW8aag==}
|
||||
dev: false
|
||||
|
||||
/solid-js/1.4.2:
|
||||
resolution: {integrity: sha512-IU5yKuT8P/n5F5g8j1rTXqxUdPYmoZDk/074TG94AEYf/nyXAeG82BSge4/lLIbCfUcnGUJ6DRdebIjujOAYyg==}
|
||||
|
||||
|
@ -12019,7 +12141,7 @@ packages:
|
|||
resolution: {integrity: sha512-iwbgdBzQSxBKoxkzaZgC9MGGUsHWJ74at9i7FF0naoqtwGuKdLYOgOJ9QRlA353DHDS/ttH2e0SRS6s3gz8NLQ==}
|
||||
dependencies:
|
||||
nanostores: 0.5.12
|
||||
solid-js: 1.4.2
|
||||
solid-js: 1.3.17
|
||||
dev: false
|
||||
|
||||
/sorcery/0.10.0:
|
||||
|
@ -12364,8 +12486,8 @@ packages:
|
|||
resolution: {integrity: sha512-fN2YRm/bGumvjUpu6yI3BpvZnpIm9I6A7HR4oUNYd7ggYyIwSA/BX7DJ+UXXffLp6XNcUijyLvttbPVCYa/3xQ==}
|
||||
engines: {node: '>= 8'}
|
||||
|
||||
/svelte2tsx/0.5.10_wwvk7nlptlrqo2czohjtk6eiqm:
|
||||
resolution: {integrity: sha512-nokQ0HTTWMcNX6tLrDLiOmJCuqjKZU9nCZ6/mVuCL3nusXdbp+9nv69VG2pCy7uQC66kV4Ls+j0WfvvJuGVnkg==}
|
||||
/svelte2tsx/0.5.9_wwvk7nlptlrqo2czohjtk6eiqm:
|
||||
resolution: {integrity: sha512-xTDASjlh+rKo4QRhTRYSH87sS7fRoyX67xhGIMPKa3FYqftRHRmMes6nVgEskiuhBovslNHYYpMMg5YM5n/STg==}
|
||||
peerDependencies:
|
||||
svelte: ^3.24
|
||||
typescript: ^4.1.2
|
||||
|
@ -12989,9 +13111,9 @@ packages:
|
|||
inherits: 2.0.4
|
||||
is-arguments: 1.1.1
|
||||
is-generator-function: 1.0.10
|
||||
is-typed-array: 1.1.9
|
||||
is-typed-array: 1.1.8
|
||||
safe-buffer: 5.2.1
|
||||
which-typed-array: 1.1.8
|
||||
which-typed-array: 1.1.7
|
||||
dev: false
|
||||
|
||||
/uvu/0.5.3:
|
||||
|
@ -13056,7 +13178,7 @@ packages:
|
|||
debug: 4.3.4
|
||||
fast-glob: 3.2.11
|
||||
pretty-bytes: 5.6.0
|
||||
rollup: 2.74.1
|
||||
rollup: 2.72.1
|
||||
workbox-build: 6.5.3
|
||||
workbox-window: 6.5.3
|
||||
transitivePeerDependencies:
|
||||
|
@ -13266,16 +13388,16 @@ packages:
|
|||
load-yaml-file: 0.2.0
|
||||
path-exists: 4.0.0
|
||||
|
||||
/which-typed-array/1.1.8:
|
||||
resolution: {integrity: sha512-Jn4e5PItbcAHyLoRDwvPj1ypu27DJbtdYXUa5zsinrUx77Uvfb0cXwwnGMTn7cjUfhhqgVQnVJCwF+7cgU7tpw==}
|
||||
/which-typed-array/1.1.7:
|
||||
resolution: {integrity: sha512-vjxaB4nfDqwKI0ws7wZpxIlde1XrLX5uB0ZjpfshgmapJMD7jJWhZI+yToJTqaFByF0eNBcYxbjmCzoRP7CfEw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
dependencies:
|
||||
available-typed-arrays: 1.0.5
|
||||
call-bind: 1.0.2
|
||||
es-abstract: 1.20.1
|
||||
for-each: 0.3.3
|
||||
foreach: 2.0.6
|
||||
has-tostringtag: 1.0.0
|
||||
is-typed-array: 1.1.9
|
||||
is-typed-array: 1.1.8
|
||||
dev: false
|
||||
|
||||
/which/1.3.1:
|
||||
|
@ -13330,19 +13452,19 @@ packages:
|
|||
'@babel/core': 7.18.0
|
||||
'@babel/preset-env': 7.18.0_@babel+core@7.18.0
|
||||
'@babel/runtime': 7.18.0
|
||||
'@rollup/plugin-babel': 5.3.1_ykg7cmcqpmn5fbkb5gxs7i3du4
|
||||
'@rollup/plugin-node-resolve': 11.2.1_rollup@2.74.1
|
||||
'@rollup/plugin-replace': 2.4.2_rollup@2.74.1
|
||||
'@rollup/plugin-babel': 5.3.1_3gvlzenj6qraw2ojvkgevxalie
|
||||
'@rollup/plugin-node-resolve': 11.2.1_rollup@2.72.1
|
||||
'@rollup/plugin-replace': 2.4.2_rollup@2.72.1
|
||||
'@surma/rollup-plugin-off-main-thread': 2.2.3
|
||||
ajv: 8.11.0
|
||||
common-tags: 1.8.2
|
||||
fast-json-stable-stringify: 2.1.0
|
||||
fs-extra: 9.1.0
|
||||
glob: 7.2.3
|
||||
glob: 7.2.0
|
||||
lodash: 4.17.21
|
||||
pretty-bytes: 5.6.0
|
||||
rollup: 2.74.1
|
||||
rollup-plugin-terser: 7.0.2_rollup@2.74.1
|
||||
rollup: 2.72.1
|
||||
rollup-plugin-terser: 7.0.2_rollup@2.72.1
|
||||
source-map: 0.8.0-beta.0
|
||||
stringify-object: 3.3.0
|
||||
strip-comments: 2.0.1
|
||||
|
|
Loading…
Reference in a new issue