-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(alpinejs): allow customizing the Alpine instance (#9751)
* feat(alpinejs): allows customzing the Alpine instance * chore: add e2e tests * fix: rename script * Update index.ts * fix: lockfile
- Loading branch information
1 parent
b3f3131
commit 1153331
Showing
14 changed files
with
367 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
--- | ||
"@astrojs/alpinejs": minor | ||
--- | ||
|
||
Allows extending Alpine using the new `entrypoint` configuration | ||
|
||
You can extend Alpine by setting the `entrypoint` option to a root-relative import specifier (for example, `entrypoint: "/src/entrypoint"`). | ||
|
||
The default export of this file should be a function that accepts an Alpine instance prior to starting, allowing the use of custom directives, plugins and other customizations for advanced use cases. | ||
|
||
```js | ||
// astro.config.mjs | ||
import { defineConfig } from 'astro/config'; | ||
import alpine from '@astrojs/alpinejs'; | ||
|
||
export default defineConfig({ | ||
// ... | ||
integrations: [alpine({ entrypoint: '/src/entrypoint' })], | ||
}); | ||
``` | ||
|
||
```js | ||
// src/entrypoint.ts | ||
import type { Alpine } from 'alpinejs' | ||
|
||
export default (Alpine: Alpine) => { | ||
Alpine.directive('foo', el => { | ||
el.textContent = 'bar'; | ||
}) | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { expect } from '@playwright/test'; | ||
import { prepareTestFactory } from './test-utils.js'; | ||
|
||
const { test } = prepareTestFactory({ root: './fixtures/basics/' }); | ||
|
||
test.describe('Basics', () => { | ||
test('Alpine is working', async ({ page, astro }) => { | ||
await page.goto(astro.resolveUrl('/')); | ||
|
||
const el = page.locator("#foo") | ||
expect(await el.textContent()).toBe('bar') | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { expect } from '@playwright/test'; | ||
import { prepareTestFactory } from './test-utils.js'; | ||
|
||
const { test } = prepareTestFactory({ root: './fixtures/basics/' }); | ||
|
||
test.describe('Basics', () => { | ||
test('Alpine is working', async ({ page, astro }) => { | ||
await page.goto(astro.resolveUrl('/')); | ||
|
||
const el = page.locator('#foo'); | ||
expect(await el.textContent()).toBe('bar'); | ||
}); | ||
}); |
6 changes: 6 additions & 0 deletions
6
packages/integrations/alpinejs/test/fixtures/basics/astro.config.mjs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import { defineConfig } from 'astro/config'; | ||
import alpine from '@astrojs/alpinejs'; | ||
|
||
export default defineConfig({ | ||
integrations: [alpine()], | ||
}) |
11 changes: 11 additions & 0 deletions
11
packages/integrations/alpinejs/test/fixtures/basics/package.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
{ | ||
"name": "@test/alpinejs-basics", | ||
"version": "0.0.0", | ||
"private": true, | ||
"dependencies": { | ||
"@astrojs/alpinejs": "workspace:*", | ||
"@types/alpinejs": "^3.13.5", | ||
"alpinejs": "^3.13.3", | ||
"astro": "workspace:*" | ||
} | ||
} |
8 changes: 8 additions & 0 deletions
8
packages/integrations/alpinejs/test/fixtures/basics/src/pages/index.astro
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
<html> | ||
<head> | ||
<title>Testing</title> | ||
</head> | ||
<body> | ||
<div id="foo" x-data="{ foo: 'bar' }" x-text="foo"></div> | ||
</body> | ||
</html> |
8 changes: 8 additions & 0 deletions
8
packages/integrations/alpinejs/test/fixtures/directive/astro.config.mjs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import { defineConfig } from 'astro/config'; | ||
import alpine from '@astrojs/alpinejs'; | ||
|
||
export default defineConfig({ | ||
integrations: [alpine({ | ||
entrypoint: "./src/entrypoint.ts" | ||
})], | ||
}) |
11 changes: 11 additions & 0 deletions
11
packages/integrations/alpinejs/test/fixtures/directive/package.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
{ | ||
"name": "@test/alpinejs-directive", | ||
"version": "0.0.0", | ||
"private": true, | ||
"dependencies": { | ||
"@astrojs/alpinejs": "workspace:*", | ||
"@types/alpinejs": "^3.13.5", | ||
"alpinejs": "^3.13.3", | ||
"astro": "workspace:*" | ||
} | ||
} |
7 changes: 7 additions & 0 deletions
7
packages/integrations/alpinejs/test/fixtures/directive/src/entrypoint.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import type { Alpine } from 'alpinejs' | ||
|
||
export default (Alpine: Alpine) => { | ||
Alpine.directive('foo', el => { | ||
el.textContent = 'bar'; | ||
}) | ||
} |
8 changes: 8 additions & 0 deletions
8
packages/integrations/alpinejs/test/fixtures/directive/src/pages/index.astro
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
<html> | ||
<head> | ||
<title>Testing</title> | ||
</head> | ||
<body> | ||
<div id="foo" x-data x-foo></div> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
import { expect, test as testBase } from '@playwright/test'; | ||
import fs from 'node:fs/promises'; | ||
import path from 'node:path'; | ||
import { fileURLToPath } from 'node:url'; | ||
import { loadFixture as baseLoadFixture } from '../../../astro/test/test-utils.js'; | ||
|
||
export const isWindows = process.platform === 'win32'; | ||
|
||
// Get all test files in directory, assign unique port for each of them so they don't conflict | ||
const testFiles = await fs.readdir(new URL('.', import.meta.url)); | ||
const testFileToPort = new Map(); | ||
for (let i = 0; i < testFiles.length; i++) { | ||
const file = testFiles[i]; | ||
if (file.endsWith('.test.js')) { | ||
testFileToPort.set(file.slice(0, -8), 4000 + i); | ||
} | ||
} | ||
|
||
export function loadFixture(inlineConfig) { | ||
if (!inlineConfig?.root) throw new Error("Must provide { root: './fixtures/...' }"); | ||
|
||
// resolve the relative root (i.e. "./fixtures/tailwindcss") to a full filepath | ||
// without this, the main `loadFixture` helper will resolve relative to `packages/astro/test` | ||
return baseLoadFixture({ | ||
...inlineConfig, | ||
root: fileURLToPath(new URL(inlineConfig.root, import.meta.url)), | ||
server: { | ||
port: testFileToPort.get(path.basename(inlineConfig.root)), | ||
}, | ||
}); | ||
} | ||
|
||
export function testFactory(inlineConfig) { | ||
let fixture; | ||
|
||
const test = testBase.extend({ | ||
astro: async ({}, use) => { | ||
fixture = fixture || (await loadFixture(inlineConfig)); | ||
await use(fixture); | ||
}, | ||
}); | ||
|
||
test.afterEach(() => { | ||
fixture.resetAllFiles(); | ||
}); | ||
|
||
return test; | ||
} | ||
|
||
/** | ||
* | ||
* @param {string} page | ||
* @returns {Promise<{message: string, hint: string, absoluteFileLocation: string, fileLocation: string}>} | ||
*/ | ||
export async function getErrorOverlayContent(page) { | ||
const overlay = await page.waitForSelector('vite-error-overlay', { | ||
strict: true, | ||
timeout: 10 * 1000, | ||
}); | ||
|
||
expect(overlay).toBeTruthy(); | ||
|
||
const message = await overlay.$$eval('#message-content', (m) => m[0].textContent); | ||
const hint = await overlay.$$eval('#hint-content', (m) => m[0].textContent); | ||
const [absoluteFileLocation, fileLocation] = await overlay.$$eval('#code header h2', (m) => [ | ||
m[0].title, | ||
m[0].textContent, | ||
]); | ||
return { message, hint, absoluteFileLocation, fileLocation }; | ||
} | ||
|
||
/** | ||
* Wait for `astro-island` that contains the `el` to hydrate | ||
* @param {import('@playwright/test').Page} page | ||
* @param {import('@playwright/test').Locator} el | ||
*/ | ||
export async function waitForHydrate(page, el) { | ||
const astroIsland = page.locator('astro-island', { has: el }); | ||
const astroIslandId = await astroIsland.last().getAttribute('uid'); | ||
await page.waitForFunction( | ||
(selector) => document.querySelector(selector)?.hasAttribute('ssr') === false, | ||
`astro-island[uid="${astroIslandId}"]` | ||
); | ||
} | ||
|
||
/** | ||
* Scroll to element manually without making sure the `el` is stable | ||
* @param {import('@playwright/test').Locator} el | ||
*/ | ||
export async function scrollToElement(el) { | ||
await el.evaluate((node) => { | ||
node.scrollIntoView({ behavior: 'auto' }); | ||
}); | ||
} | ||
|
||
export function prepareTestFactory(opts) { | ||
const test = testFactory(opts); | ||
|
||
let devServer; | ||
|
||
test.beforeAll(async ({ astro }) => { | ||
devServer = await astro.startDevServer(); | ||
}); | ||
|
||
test.afterAll(async () => { | ||
await devServer.stop(); | ||
}); | ||
|
||
return { | ||
test, | ||
}; | ||
} |
Oops, something went wrong.