Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions .gitattributes

This file was deleted.

43 changes: 43 additions & 0 deletions .github/workflows/browser-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: Browser Tests

defaults:
run:
shell: bash

on:
push:
paths-ignore:
- 'src/*/doc/**'
- 'src/**/*.md'
- 'ux.symfony.com/**'
- '.github/workflows/app-tests.yaml'
- '.github/workflows/unit-tests.yaml'
pull_request:
paths-ignore:
- 'src/*/doc/**'
- 'src/**/*.md'
- 'ux.symfony.com/**'
- '.github/workflows/app-tests.yaml'
- '.github/workflows/unit-tests.yaml'

jobs:
js:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm i -g corepack && corepack enable
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'pnpm'
cache-dependency-path: |
pnpm-lock.yaml
package.json
src/**/package.json
- run: pnpm install --frozen-lockfile

- name: Install browsers
run: node ./bin/get_browsers.mjs

# TODO: Install the E2E app + run webserver
- run: pnpm run test:browser
1 change: 1 addition & 0 deletions .github/workflows/functional-tests.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# Deprecated, will be removed in favor of browser-tests.yml
name: Functional Tests

defaults:
Expand Down
9 changes: 2 additions & 7 deletions .github/workflows/unit-tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -143,21 +143,16 @@ jobs:
fi
js:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
node-version: [ '18.x', '20.x', '22.x', '24.x' ]
Comment on lines -146 to -149
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no need to unit tests in multiple Node.js versions, our assets/ code is supposed to run in a browser. We are testing the strict necessary

steps:
- uses: actions/checkout@v4
- run: npm i -g corepack && corepack enable
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
node-version-file: '.nvmrc'
cache: 'pnpm'
cache-dependency-path: |
pnpm-lock.yaml
package.json
src/**/package.json
- run: pnpm install --frozen-lockfile
- run: pnpm exec playwright install chromium
- run: pnpm run test
- run: pnpm run test:unit
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
vendor/
node_modules

.doctor-rst.cache
Expand All @@ -7,3 +6,5 @@ node_modules

/composer.lock
/vendor

/browsers
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
22.11
22.18
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I can use import.meta.main (like __name__ == '__main__' in Python)

8 changes: 6 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ To set up the development environment, you need the following tools:

- [PHP](https://www.php.net/downloads.php) 8.1 or higher
- [Composer](https://getcomposer.org/download/)
- [Node.js](https://nodejs.org/en/download/package-manager) 22.11 or higher
- [Node.js](https://nodejs.org/en/download/package-manager) 22.18 or higher
- [Corepack](https://github.com/nodejs/corepack)
- [PNPM](https://pnpm.io/) 10.13 or higher

Expand Down Expand Up @@ -82,12 +82,16 @@ To help you with assets, you can run the following commands in a specific packag
- `pnpm run build`: build (compile) assets from the package,
- `pnpm run watch`: watch for modifications and rebuild assets from the package,
- `pnpm run test`: run the tests from the package,
- `pnpm run test:unit`: run the Unit tests from the package,
- `pnpm run test:browser`: run the Browser tests from the package,
- `pnpm run check`: run the formatter, linter, and sort imports, and fails if any modifications
- `pnpm run check --write`: run the formatter, linter, imports sorting, and write modifications

Thanks to [PNPM Workspaces](https://pnpm.io/workspaces), you can also run these commands from the root directory of the project:
- `pnpm run build`: build (compile) assets from **all** packages,
- `pnpm run test`: run the tests from **all** packages,
- `pnpm run test:unit`: run the Unit tests from **all** packages,
- `pnpm run test:browser`: run the Browser tests from **all** packages,
- `pnpm run check`: run the formatter, linter, and sort imports for **all** packages, and fails if any modifications
- `pnpm run check --write`: run the formatter, linter, imports sorting for **all** packages, and write modifications

Expand All @@ -112,7 +116,7 @@ docker run --rm -it -e DOCS_DIR='/docs' -v ${PWD}:/docs oskarstark/doctor-rst -
```shell
$ git checkout 2.x && \
git fetch upstream && \
git rebase upstream/2.x && \
git reset --hard upstream/2.x && \
git push origin 2.x
```

Expand Down
50 changes: 50 additions & 0 deletions bin/get_browsers.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import * as path from 'node:path';
import {
Browser,
BrowserTag,
detectBrowserPlatform,
install as installBrowser,
resolveBuildId,
} from '@puppeteer/browsers';

const platform = detectBrowserPlatform();
const installBrowserCommonOpts = {
platform,
cacheDir: path.join(import.meta.dirname, '../browsers'),
downloadProgressCallback: 'default',
};

// Lowest versions are computed from "defaults and fully supports es6-module" query,
// see https://browsersl.ist/#q=defaults+and+fully+supports+es6-module

export const browsers = {
'chrome@lowest': await installBrowser({
...installBrowserCommonOpts,
browser: Browser.CHROME,
// The lowest version where:
// - Chrome and associated Chromedriver could easily be downloaded
// - there is no compatibility issues like "WebDriver Bidi command \"session.subscribe\" failed with error"
// - there is no timeout issues when requesting Vitest webserver
// @see https://raw.githubusercontent.com/GoogleChromeLabs/chrome-for-testing/refs/heads/main/data/known-good-versions-with-downloads.json
buildId: '130.0.6669.0',
}),
'chrome@latest': await installBrowser({
...installBrowserCommonOpts,
browser: Browser.CHROME,
buildId: await resolveBuildId(Browser.CHROME, platform, BrowserTag.STABLE),
}),
'firefox@lowest': await installBrowser({
...installBrowserCommonOpts,
browser: Browser.FIREFOX,
buildId: 'stable_128.0',
}),
'firefox@latest': await installBrowser({
...installBrowserCommonOpts,
browser: Browser.FIREFOX,
buildId: await resolveBuildId(Browser.FIREFOX, platform, BrowserTag.STABLE),
}),
};

if (import.meta.main) {
console.log('Browsers installed:', browsers);
}
57 changes: 37 additions & 20 deletions bin/test_package.sh
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the future, it would be nice to shift the 1st argument (package location) and pass all the other arsg to pnpm exec vitest

Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,9 @@ PROJECT_DIR=$(dirname "$SCRIPT_DIR")
# Flag to track if any test fails
all_tests_passed=true

# Check if we have at least one argument
if [ $# -eq 0 ]
then
echo "No arguments supplied, please provide the package's path."
# Check if we have enough arguments
if [ $# -ne 2 ]; then
echo "No arguments supplied, please provide the package's path and the test type (e.g. --unit or --browser)"
fi

# Check if jq is installed
Expand All @@ -22,46 +21,58 @@ if ! command -v jq &> /dev/null; then
fi

runTestSuite() {
echo -e "Running tests for $workspace...\n"
pnpm exec vitest --run || { all_tests_passed=false; }
local testProject="$1"
if [ "$testProject" != "unit" ] && [ "$testProject" != "browser" ]; then
echo "Unknown test project: $testProject. Please use 'unit' or 'browser'."
exit 1
fi

echo -e "🧪 Running $testProject tests for $workspace...\n"
pnpm exec vitest --run --config "vitest.config.$testProject.mjs" || { all_tests_passed=false; }
}

processWorkspace() {
local location="$1"
local testProject="$2"

if [ ! -d "$location" ]; then
echo "No directory found at $location"
echo "No directory found at $location"
return
fi

package_json_path="$location/package.json"
if [ ! -f "$package_json_path" ]; then
echo "No package.json found at $package_json_path"
echo "No package.json found at $package_json_path"
return
fi

workspace=$(jq -r '.name' "$package_json_path")
if [ -z "$workspace" ]; then
echo "No name found in package.json at $package_json_path"
echo "No name found in package.json at $package_json_path"
return
fi

echo -e "Processing workspace $workspace at location $location...\n"
echo -e "Processing workspace $workspace at location $location...\n"

echo "Checking '$package_json_path' for peerDependencies and importmap dependencies to have the same version"
echo "⚙️ Checking '$package_json_path' for peerDependencies and importmap dependencies to have the same version"
deps=$(jq -r '.peerDependencies | keys[]' "$package_json_path")
for library in $deps; do
version=$(jq -r ".peerDependencies.\"$library\"" "$package_json_path")
importmap_version=$(jq -r ".symfony.importmap.\"$library\"" "$package_json_path")
importmap_version=$(jq -r ".symfony.importmap.\"$library\" | if type == \"string\" then . else .version end" "$package_json_path")

if [ "$importmap_version" == null ]; then
echo " ⚠ No importmap version found for $library in $package_json_path, skipping..."
continue
fi

if [ "$version" != "$importmap_version" ]; then
echo " -> Version mismatch for $library: $version (peerDependencies) vs $importmap_version (importmap)"
echo " -> You need to match the version of the \"peerDependency\" with the version in the \"importmap\""
exit
echo " Version mismatch for $library: $version (peerDependencies) vs $importmap_version (importmap)"
echo " You need to match the version of the \"peerDependency\" with the version in the \"importmap\""
exit 1
fi
done

echo "Checking '$package_json_path' for peerDependencies with multiple versions defined"
echo "⚙️ Checking '$package_json_path' for peerDependencies with multiple versions defined"
deps_with_multiple_versions=$(jq -r '.peerDependencies | to_entries[] | select(.value | contains("||")) | .key' "$package_json_path")

if [ -n "$deps_with_multiple_versions" ]; then
Expand All @@ -78,20 +89,26 @@ processWorkspace() {
echo -e " - Install $library@$trimmed_version for $workspace\n"
pnpm add "$library@$trimmed_version" --save-peer --filter "$workspace"

runTestSuite
runTestSuite "$testProject"
fi
done
done

echo " -> Reverting version changes from $package_json_path"
git checkout -- "$package_json_path"
git checkout -- "$package_json_path" "$PROJECT_DIR/pnpm-lock.yaml"
else
echo -e " -> No peerDependencies found with multiple versions defined\n"
runTestSuite
runTestSuite "$testProject"
fi
}

processWorkspace "$(realpath "$PWD/$1")"
case "$2" in
--unit) testProject="unit" ;;
--browser) testProject="browser" ;;
*) echo "Unknown test type: $2. Please use --unit or --browser."; exit 1 ;;
esac

processWorkspace "$(realpath "$PWD/$1")" "$testProject"

# Check the flag at the end and exit with code 1 if any test failed
if [ "$all_tests_passed" = false ]; then
Expand Down
4 changes: 3 additions & 1 deletion biome.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,16 @@
"**/*.json",
"**/*.md",
"**/bin/**/*.js",
"**/src/**/assets/*.mjs",
"**/src/**/assets/src/**",
"**/src/**/assets/test/**",
"!**/composer.json",
"!**/vendor",
"!**/package.json",
"!**/node_modules",
"!**/var",
"!**/dist"
"!**/dist",
"!**/browsers"
]
},
"linter": {
Expand Down
11 changes: 7 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,28 +1,31 @@
{
"private": true,
"packageManager": "pnpm@10.13.1+sha512.37ebf1a5c7a30d5fabe0c5df44ee8da4c965ca0c5af3dbab28c3a1681b70a256218d05c81c9c0dcf767ef6b8551eb5b960042b9ed4300c59242336377e01cfad",
"packageManager": "pnpm@10.14.0+sha512.ad27a79641b49c3e481a16a805baa71817a04bbe06a38d17e60e2eaee83f6a146c6a688125f5792e48dd5ba30e7da52a5cda4c3992b9ccf333f9ce223af84748",
"type": "module",
"workspaces": [
"src/*/assets",
"src/*/src/Bridge/*/assets"
],
"scripts": {
"build": "pnpm run --filter @symfony/ux-map build && pnpm run -r --aggregate-output build",
"test": "pnpm run -r --aggregate-output test",
"test": "pnpm run -r --workspace-concurrency=1 test",
"test:unit": "pnpm run -r --aggregate-output test:unit",
"test:browser": "pnpm run -r --workspace-concurrency=1 test:browser",
"check": "biome check",
"ci": "biome ci"
},
"devDependencies": {
"@biomejs/biome": "^2.0.4",
"@puppeteer/browsers": "^2.10.6",
"@testing-library/dom": "^10.4.0",
"@testing-library/jest-dom": "^6.6.3",
"@types/node": "^22.6.0",
"lightningcss": "^1.28.2",
"pkg-types": "^2.2.0",
"playwright": "^1.47.0",
"tinyglobby": "^0.2.14",
"tsup": "^8.5.0",
"vitest": "^3.2.4"
"vitest": "^3.2.4",
"webdriverio": "^9.19.1"
},
"version": "2.27.0"
}
Loading
Loading