')
expect(html).toContain('
Fallback
')
+ // ensure components are not rendered server-side
expect(html).not.toContain('Should not be server rendered')
await expectNoClientErrors('/client-only-components')
+
+ const page = await createPage('/client-only-components')
+
+ await page.waitForLoadState('networkidle')
+
+ const hiddenSelectors = [
+ '.string-stateful-should-be-hidden',
+ '.client-script-should-be-hidden',
+ '.string-stateful-script-should-be-hidden',
+ '.no-state-hidden'
+ ]
+ const visibleSelectors = [
+ '.string-stateful',
+ '.string-stateful-script',
+ '.client-only-script',
+ '.client-only-script-setup',
+ '.no-state'
+ ]
+ // ensure directives are correctly applied
+ await Promise.all(hiddenSelectors.map(selector => page.locator(selector).isHidden()))
+ .then(results => results.forEach(isHidden => expect(isHidden).toBeTruthy()))
+ // ensure hidden components are still rendered
+ await Promise.all(hiddenSelectors.map(selector => page.locator(selector).innerHTML()))
+ .then(results => results.forEach(innerHTML => expect(innerHTML).not.toBe('')))
+
+ // ensure single root node components are rendered once on client (should not be empty)
+ await Promise.all(visibleSelectors.map(selector => page.locator(selector).innerHTML()))
+ .then(results => results.forEach(innerHTML => expect(innerHTML).not.toBe('')))
+
+ // ensure multi-root-node is correctly rendered
+ expect(await page.locator('.multi-root-node-count').innerHTML()).toContain('0')
+ expect(await page.locator('.multi-root-node-button').innerHTML()).toContain('add 1 to count')
+ expect(await page.locator('.multi-root-node-script-count').innerHTML()).toContain('0')
+ expect(await page.locator('.multi-root-node-script-button').innerHTML()).toContain('add 1 to count')
+
+ // ensure components reactivity
+ await page.locator('.multi-root-node-button').click()
+ await page.locator('.multi-root-node-script-button').click()
+ await page.locator('.client-only-script button').click()
+ await page.locator('.client-only-script-setup button').click()
+
+ expect(await page.locator('.multi-root-node-count').innerHTML()).toContain('1')
+ expect(await page.locator('.multi-root-node-script-count').innerHTML()).toContain('1')
+ expect(await page.locator('.client-only-script-setup button').innerHTML()).toContain('1')
+ expect(await page.locator('.client-only-script button').innerHTML()).toContain('1')
+
+ // ensure components ref is working and reactive
+ await page.locator('button.test-ref-1').click()
+ await page.locator('button.test-ref-2').click()
+ await page.locator('button.test-ref-3').click()
+ await page.locator('button.test-ref-4').click()
+ expect(await page.locator('.client-only-script-setup button').innerHTML()).toContain('2')
+ expect(await page.locator('.client-only-script button').innerHTML()).toContain('2')
+ expect(await page.locator('.string-stateful-script').innerHTML()).toContain('1')
+ expect(await page.locator('.string-stateful').innerHTML()).toContain('1')
+
+ // ensure directives are reactive
+ await page.locator('button#show-all').click()
+ await Promise.all(hiddenSelectors.map(selector => page.locator(selector).isVisible()))
+ .then(results => results.forEach(isVisible => expect(isVisible).toBeTruthy()))
})
})
diff --git a/test/fixtures/basic/components/client/MultiRootNode.client.vue b/test/fixtures/basic/components/client/MultiRootNode.client.vue
new file mode 100644
index 00000000000..247ad18db1a
--- /dev/null
+++ b/test/fixtures/basic/components/client/MultiRootNode.client.vue
@@ -0,0 +1,14 @@
+
+
+ {{ count }}
+
+
+
+
+
diff --git a/test/fixtures/basic/components/client/MultiRootNodeScript.client.vue b/test/fixtures/basic/components/client/MultiRootNodeScript.client.vue
new file mode 100644
index 00000000000..67ed503ca3d
--- /dev/null
+++ b/test/fixtures/basic/components/client/MultiRootNodeScript.client.vue
@@ -0,0 +1,19 @@
+
+
+ {{ count }}
+
+
+
+
+
diff --git a/test/fixtures/basic/components/client/NoState.client.vue b/test/fixtures/basic/components/client/NoState.client.vue
new file mode 100644
index 00000000000..92f3b3e3bec
--- /dev/null
+++ b/test/fixtures/basic/components/client/NoState.client.vue
@@ -0,0 +1,3 @@
+
+ Hello world !
+
diff --git a/test/fixtures/basic/components/client/Script.client.vue b/test/fixtures/basic/components/client/Script.client.vue
new file mode 100644
index 00000000000..86767ad9378
--- /dev/null
+++ b/test/fixtures/basic/components/client/Script.client.vue
@@ -0,0 +1,45 @@
+
+
+
+
+
+ client only script component {{ foo }}
+
+
+
+
+
+
+
+
+
diff --git a/test/fixtures/basic/components/client/SetupScript.client.vue b/test/fixtures/basic/components/client/SetupScript.client.vue
new file mode 100644
index 00000000000..becd6eb01e6
--- /dev/null
+++ b/test/fixtures/basic/components/client/SetupScript.client.vue
@@ -0,0 +1,18 @@
+
+
+
+
+
client only script setup component {{ props.foo }}
+
+
+
+
+
diff --git a/test/fixtures/basic/components/client/StringChildStateful.client.vue b/test/fixtures/basic/components/client/StringChildStateful.client.vue
new file mode 100644
index 00000000000..16b39a204a7
--- /dev/null
+++ b/test/fixtures/basic/components/client/StringChildStateful.client.vue
@@ -0,0 +1,14 @@
+
+
+
+ Hi i should be rendered {{ state }}
+
diff --git a/test/fixtures/basic/components/client/StringChildStatefulScript.client.vue b/test/fixtures/basic/components/client/StringChildStatefulScript.client.vue
new file mode 100644
index 00000000000..b87df7c74da
--- /dev/null
+++ b/test/fixtures/basic/components/client/StringChildStatefulScript.client.vue
@@ -0,0 +1,18 @@
+
+
+
+ Hi i should be rendered {{ state }}
+
diff --git a/test/fixtures/basic/pages/client-only-components.vue b/test/fixtures/basic/pages/client-only-components.vue
index f020ea1cfc1..e5e1094a92e 100644
--- a/test/fixtures/basic/pages/client-only-components.vue
+++ b/test/fixtures/basic/pages/client-only-components.vue
@@ -1,18 +1,67 @@
-
-
+
+
Hello
-
+
Should not be server rendered.
Fallback
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+