fix(wab): keep newly inserted inline tags inline while editing rich text #777
This file contains hidden or 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
| name: Tests | |
| on: | |
| workflow_dispatch: # Allow manual trigger from GitHub UI | |
| push: | |
| branches: [master] | |
| paths: | |
| - 'platform/wab/**' | |
| - 'platform/loader-bundle-env/**' | |
| - 'platform/canvas-packages/**' | |
| - 'packages/**' | |
| - 'plasmicpkgs/**' | |
| - '.github/workflows/tests.yml' | |
| - '.github/actions/setup-env/**' | |
| pull_request: | |
| branches: [master] | |
| paths: | |
| - 'platform/wab/**' | |
| - 'platform/loader-bundle-env/**' | |
| - 'platform/canvas-packages/**' | |
| - 'packages/**' | |
| - 'plasmicpkgs/**' | |
| - '.github/workflows/tests.yml' | |
| - '.github/actions/setup-env/**' | |
| jobs: | |
| setup: | |
| name: Setup & Build | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup environment | |
| uses: ./.github/actions/setup-env | |
| - name: Install root dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Install platform/wab dependencies | |
| working-directory: platform/wab | |
| run: yarn install --frozen-lockfile | |
| - name: Install loader-bundle-env dependencies | |
| working-directory: platform/loader-bundle-env | |
| run: yarn install --frozen-lockfile | |
| - name: Generate required files (PEG parsers, model classes) | |
| working-directory: platform/wab | |
| run: make | |
| # Fast check (~2 min) that EP-specific customizations haven't been dropped. | |
| # Runs on all PRs without labels. Blocks merge if any EP dep/file is missing. | |
| test-ep-integrity: | |
| name: EP Fork Integrity | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '22' | |
| - name: Install WAB dependencies | |
| working-directory: platform/wab | |
| run: yarn install --frozen-lockfile | |
| - name: Run EP integrity tests | |
| working-directory: platform/wab | |
| run: | | |
| NODE_OPTIONS='--max-old-space-size=4096' npx jest --runInBand --forceExit \ | |
| --testPathPattern='ep-fork-integrity' --no-coverage | |
| test-wab: | |
| name: WAB Tests (Shard ${{ matrix.shard }}/4) | |
| needs: setup | |
| runs-on: ubuntu-latest | |
| # Only run if manually triggered or PR has 'run-wab-tests' label | |
| if: | | |
| github.event_name == 'workflow_dispatch' || | |
| github.event_name == 'push' || | |
| contains(github.event.pull_request.labels.*.name, 'run-wab-tests') | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| shard: [1, 2, 3, 4] | |
| services: | |
| postgres: | |
| image: postgres:15 | |
| env: | |
| POSTGRES_USER: postgres | |
| POSTGRES_PASSWORD: postgres | |
| POSTGRES_DB: postgres | |
| POSTGRES_HOST_AUTH_METHOD: trust | |
| ports: | |
| - 5432:5432 | |
| options: >- | |
| --health-cmd pg_isready | |
| --health-interval 10s | |
| --health-timeout 5s | |
| --health-retries 5 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup environment | |
| uses: ./.github/actions/setup-env | |
| with: | |
| fail-on-cache-miss: 'true' | |
| - name: Free disk space | |
| run: | | |
| sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc | |
| df -h | |
| - name: Validate cached dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Ensure platform/wab binaries | |
| working-directory: platform/wab | |
| run: yarn install --frozen-lockfile --check-files | |
| - name: Generate required files (PEG parsers, model classes) | |
| working-directory: platform/wab | |
| run: make | |
| - name: Setup PostgreSQL users and extensions | |
| env: | |
| PGPASSWORD: postgres | |
| PGHOST: localhost | |
| PGUSER: postgres | |
| run: | | |
| psql -c "CREATE USER wab PASSWORD 'SEKRET';" | |
| psql -c "CREATE USER superwab PASSWORD 'SEKRET' CREATEDB CREATEROLE IN GROUP wab;" | |
| psql -c "GRANT pg_signal_backend TO superwab;" | |
| psql -c "CREATE DATABASE wab OWNER wab;" | |
| psql -c "CREATE EXTENSION IF NOT EXISTS \"uuid-ossp\";" | |
| psql -c "CREATE EXTENSION IF NOT EXISTS pgcrypto;" | |
| - name: Run WAB Jest tests (Shard ${{ matrix.shard }}/4) | |
| working-directory: platform/wab | |
| env: | |
| CI: true | |
| NODE_OPTIONS: '--max-old-space-size=8192' | |
| run: yarn test:ci --shard=${{ matrix.shard }}/4 --testPathIgnorePatterns='loader.spec.ts' | |
| - name: Test Summary | |
| if: always() | |
| run: | | |
| echo "### WAB Test Results (Shard ${{ matrix.shard }}/4)" >> $GITHUB_STEP_SUMMARY | |
| if [ "${{ job.status }}" == "success" ]; then | |
| echo "All tests passed." >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "Some tests failed." >> $GITHUB_STEP_SUMMARY | |
| fi | |
| # Isolated runner for loader HTML tests. These tests spawn a subprocess | |
| # (~500MB-1GB) to render HTML previews. When run alongside other Jest tests | |
| # on the same 7GB runner (with Jest's 8GB heap), the subprocess OOMs. | |
| # Running on a dedicated runner with a 4GB Jest heap leaves room for the | |
| # subprocess. The sharded WAB tests exclude loader.spec.ts via | |
| # --testPathIgnorePatterns to avoid duplication. | |
| test-wab-loader: | |
| name: WAB Loader HTML Tests | |
| needs: setup | |
| runs-on: ubuntu-latest | |
| if: | | |
| github.event_name == 'workflow_dispatch' || | |
| github.event_name == 'push' || | |
| contains(github.event.pull_request.labels.*.name, 'run-wab-tests') | |
| services: | |
| postgres: | |
| image: postgres:15 | |
| env: | |
| POSTGRES_USER: postgres | |
| POSTGRES_PASSWORD: postgres | |
| POSTGRES_DB: postgres | |
| POSTGRES_HOST_AUTH_METHOD: trust | |
| ports: | |
| - 5432:5432 | |
| options: >- | |
| --health-cmd pg_isready | |
| --health-interval 10s | |
| --health-timeout 5s | |
| --health-retries 5 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup environment | |
| uses: ./.github/actions/setup-env | |
| with: | |
| fail-on-cache-miss: 'true' | |
| - name: Free disk space | |
| run: | | |
| sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc | |
| df -h | |
| - name: Validate cached dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Ensure platform/wab binaries | |
| working-directory: platform/wab | |
| run: yarn install --frozen-lockfile --check-files | |
| - name: Generate required files (PEG parsers, model classes) | |
| working-directory: platform/wab | |
| run: make | |
| - name: Setup PostgreSQL users and extensions | |
| env: | |
| PGPASSWORD: postgres | |
| PGHOST: localhost | |
| PGUSER: postgres | |
| run: | | |
| psql -c "CREATE USER wab PASSWORD 'SEKRET';" | |
| psql -c "CREATE USER superwab PASSWORD 'SEKRET' CREATEDB CREATEROLE IN GROUP wab;" | |
| psql -c "GRANT pg_signal_backend TO superwab;" | |
| psql -c "CREATE DATABASE wab OWNER wab;" | |
| psql -c "CREATE EXTENSION IF NOT EXISTS \"uuid-ossp\";" | |
| psql -c "CREATE EXTENSION IF NOT EXISTS pgcrypto;" | |
| - name: Install loader-bundle-env dependencies | |
| working-directory: platform/loader-bundle-env | |
| run: yarn install --frozen-lockfile | |
| - name: Run loader HTML tests | |
| working-directory: platform/wab | |
| env: | |
| CI: true | |
| NODE_OPTIONS: '--max-old-space-size=4096' | |
| HTML_PREVIEW_POOL_SIZE: '1' | |
| run: yarn test:ci --testPathPattern='loader.spec.ts' | |
| - name: Test Summary | |
| if: always() | |
| run: | | |
| echo "### WAB Loader HTML Test Results" >> $GITHUB_STEP_SUMMARY | |
| if [ "${{ job.status }}" == "success" ]; then | |
| echo "All tests passed." >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "Some tests failed." >> $GITHUB_STEP_SUMMARY | |
| fi | |
| test-packages: | |
| name: SDK Packages Tests | |
| # No needs: runs in parallel with setup (doesn't need generated files) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup environment | |
| uses: ./.github/actions/setup-env | |
| # Cache speeds up the install but isn't required | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Debug environment | |
| run: | | |
| echo "Node version: $(node -v)" | |
| echo "npm version: $(npm -v)" | |
| echo "TypeScript version: $(npx tsc --version)" | |
| echo "Root SWR version: $(cat node_modules/swr/package.json | grep version)" | |
| echo "packages/query SWR exists: $(ls packages/query/node_modules/swr/package.json 2>/dev/null && cat packages/query/node_modules/swr/package.json | grep version || echo 'NOT FOUND')" | |
| - name: Build SDK packages | |
| run: pnpm lerna run build --scope '@plasmicapp/*' --verbose | |
| - name: Run SDK packages Jest tests | |
| env: | |
| CI: true | |
| NODE_OPTIONS: '--max-old-space-size=4096 --experimental-vm-modules' | |
| run: pnpm jest --testPathPattern='packages/' --testPathIgnorePatterns='packages/data-sources/src|packages/host/src|packages/plasmic-mcp' --passWithNoTests | |
| - name: Run SDK packages Vitest tests (data-sources) | |
| env: | |
| CI: true | |
| working-directory: packages/data-sources | |
| run: pnpm test | |
| - name: Run SDK packages Vitest tests (host) | |
| env: | |
| CI: true | |
| working-directory: packages/host | |
| run: pnpm test | |
| - name: Test Summary | |
| if: always() | |
| run: | | |
| echo "### SDK Packages Test Results" >> $GITHUB_STEP_SUMMARY | |
| if [ "${{ job.status }}" == "success" ]; then | |
| echo "All tests passed." >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "Some tests failed." >> $GITHUB_STEP_SUMMARY | |
| fi | |
| test-plasmicpkgs: | |
| name: Plasmic Packages Tests | |
| # No needs: runs in parallel with setup (doesn't need generated files) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup environment | |
| uses: ./.github/actions/setup-env | |
| # Cache speeds up the install but isn't required | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Build @plasmicapp/host and @plasmicpkgs/commerce | |
| run: pnpm lerna run build --scope '@plasmicapp/host' --scope '@plasmicpkgs/commerce' | |
| - name: Run plasmicpkgs Jest tests | |
| env: | |
| CI: true | |
| NODE_OPTIONS: '--max-old-space-size=4096 --experimental-vm-modules' | |
| run: pnpm jest --testPathPattern='plasmicpkgs/' --testPathIgnorePatterns='plasmicpkgs/wordpress|plasmicpkgs/contentful|plasmicpkgs/commerce-providers/elastic-path/src/auth/ep-plugin' --passWithNoTests | |
| - name: Run plasmicpkgs Vitest tests | |
| env: | |
| CI: true | |
| run: npx vitest run plasmicpkgs/wordpress plasmicpkgs/contentful --passWithNoTests | |
| - name: Run elastic-path Vitest tests | |
| env: | |
| CI: true | |
| working-directory: plasmicpkgs/commerce-providers/elastic-path | |
| run: pnpm vitest run | |
| - name: Test Summary | |
| if: always() | |
| run: | | |
| echo "### Plasmic Packages Test Results" >> $GITHUB_STEP_SUMMARY | |
| if [ "${{ job.status }}" == "success" ]; then | |
| echo "All tests passed." >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "Some tests failed." >> $GITHUB_STEP_SUMMARY | |
| fi | |
| test-e2e: | |
| name: E2E Tests | |
| needs: setup | |
| runs-on: ubuntu-latest | |
| # Only run if manually triggered, push, or PR has 'run-e2e-tests' label | |
| if: | | |
| github.event_name == 'workflow_dispatch' || | |
| github.event_name == 'push' || | |
| contains(github.event.pull_request.labels.*.name, 'run-e2e-tests') | |
| services: | |
| postgres: | |
| image: postgres:15 | |
| env: | |
| POSTGRES_USER: postgres | |
| POSTGRES_PASSWORD: postgres | |
| POSTGRES_DB: postgres | |
| POSTGRES_HOST_AUTH_METHOD: trust | |
| ports: | |
| - 5432:5432 | |
| options: >- | |
| --health-cmd pg_isready | |
| --health-interval 10s | |
| --health-timeout 5s | |
| --health-retries 5 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup environment | |
| uses: ./.github/actions/setup-env | |
| with: | |
| fail-on-cache-miss: 'true' | |
| - name: Free disk space | |
| run: | | |
| sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc | |
| df -h | |
| - name: Validate cached dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Ensure platform/wab binaries | |
| working-directory: platform/wab | |
| run: yarn install --frozen-lockfile --check-files | |
| - name: Generate required files (PEG parsers, model classes) | |
| working-directory: platform/wab | |
| run: make | |
| - name: Setup PostgreSQL users and extensions | |
| env: | |
| PGPASSWORD: postgres | |
| PGHOST: localhost | |
| run: | | |
| psql -U postgres -c "CREATE USER wab PASSWORD 'SEKRET';" | |
| psql -U postgres -c "CREATE USER superwab PASSWORD 'SEKRET' CREATEDB CREATEROLE IN GROUP wab;" | |
| psql -U postgres -c "CREATE USER cypress PASSWORD 'SEKRET';" | |
| psql -U postgres -c "CREATE USER supertdbwab PASSWORD 'SEKRET' CREATEDB CREATEROLE IN GROUP wab;" | |
| psql -U postgres -c "GRANT pg_signal_backend TO superwab;" | |
| psql -U postgres -c "CREATE DATABASE wab OWNER wab;" | |
| psql -U postgres -d wab -c "CREATE EXTENSION IF NOT EXISTS \"uuid-ossp\";" | |
| psql -U postgres -d wab -c "CREATE EXTENSION IF NOT EXISTS pgcrypto;" | |
| - name: Run database migrations | |
| working-directory: platform/wab | |
| run: yarn typeorm migration:run | |
| - name: Seed database | |
| working-directory: platform/wab | |
| run: yarn seed | |
| - name: Build sibling packages and CSS | |
| run: | | |
| set -e # Exit on first error | |
| echo "=== Initial disk space ===" | |
| df -h | |
| echo "Building platform/sub..." | |
| (cd platform/sub && yarn && yarn build-dev) | |
| rm -rf platform/sub/node_modules | |
| echo "Cleaned up platform/sub/node_modules" | |
| echo "Building platform/live-frame..." | |
| (cd platform/live-frame && yarn && yarn build) | |
| rm -rf platform/live-frame/node_modules | |
| echo "Cleaned up platform/live-frame/node_modules" | |
| echo "Building platform/react-web-bundle..." | |
| (cd platform/react-web-bundle && yarn && yarn build) | |
| rm -rf platform/react-web-bundle/node_modules | |
| echo "Cleaned up platform/react-web-bundle/node_modules" | |
| echo "Building platform/canvas-packages..." | |
| (cd platform/canvas-packages && yarn && yarn build) | |
| rm -rf platform/canvas-packages/node_modules | |
| echo "Cleaned up platform/canvas-packages/node_modules" | |
| echo "Building platform/loader-html-hydrate..." | |
| (cd platform/loader-html-hydrate && yarn && yarn build) | |
| rm -rf platform/loader-html-hydrate/node_modules | |
| echo "Cleaned up platform/loader-html-hydrate/node_modules" | |
| echo "Building CSS..." | |
| (cd platform/wab && yarn build-css) | |
| echo "Cleaning yarn cache..." | |
| # From a yarn-pinned dir: the repo root is pnpm, and yarn 1 refuses | |
| # to run against it. The cache itself is global, so this is the same | |
| # cache the sibling installs above filled. | |
| (cd platform/wab && yarn cache clean) | |
| echo "=== Final disk space ===" | |
| df -h | |
| echo "All sibling packages built successfully" | |
| - name: Build and start host-test server | |
| run: | | |
| echo "Building host-test Next.js app..." | |
| cd platform/host-test | |
| yarn install | |
| yarn build | |
| echo "Starting host-test server on port 3000..." | |
| yarn start & | |
| # Wait for it to be ready | |
| npx wait-on http://localhost:3000/plasmic-host --timeout 60000 | |
| echo "Host-test server is ready" | |
| - name: Install Playwright dependencies | |
| working-directory: platform/wab/playwright | |
| run: yarn install --frozen-lockfile | |
| - name: Install Playwright browsers | |
| working-directory: platform/wab/playwright | |
| run: npx playwright install chromium | |
| - name: Build production frontend | |
| working-directory: platform/wab | |
| run: NODE_ENV=development PUBLIC_URL=http://localhost:3003 bash tools/dev-server.bash build | |
| - name: Start application servers | |
| working-directory: platform/wab | |
| env: | |
| NODE_ENV: development | |
| CI: true | |
| TUTORIAL_DB_SUPER_PASSSWORD: SEKRET | |
| SKIP_GRANT_REVOKE_EMAILS: 'true' | |
| run: | | |
| # Start backend server in background | |
| yarn dev:backend & | |
| # Start host server in background | |
| yarn host-server & | |
| # Serve production frontend build with API proxy to backend | |
| cd build && npx -p local-web-server ws --spa index.html --port 3003 \ | |
| --cors.origin '*' \ | |
| --rewrite '/api/(.*) -> http://localhost:3004/api/$1' & | |
| cd .. | |
| # Wait for all servers to be ready | |
| npx wait-on http://localhost:3003 http://localhost:3004 http://localhost:3005 --timeout 300000 | |
| - name: Run Playwright tests | |
| working-directory: platform/wab/playwright | |
| env: | |
| CI: true | |
| run: npx playwright test | |
| - name: Upload Playwright report | |
| uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: playwright-report | |
| path: platform/wab/playwright/playwright-report/ | |
| retention-days: 30 | |
| - name: Upload test results (on failure) | |
| uses: actions/upload-artifact@v4 | |
| if: failure() | |
| with: | |
| name: playwright-test-results | |
| path: platform/wab/playwright/test-results/ | |
| retention-days: 30 | |
| - name: Test Summary | |
| if: always() | |
| run: | | |
| echo "### E2E Test Results" >> $GITHUB_STEP_SUMMARY | |
| if [ "${{ job.status }}" == "success" ]; then | |
| echo "All E2E tests passed." >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "Some E2E tests failed. Check the Playwright report artifact for details." >> $GITHUB_STEP_SUMMARY | |
| fi | |
| all-tests: | |
| name: All Tests | |
| needs: [setup, test-ep-integrity, test-wab, test-wab-loader, test-packages, test-plasmicpkgs, test-e2e] | |
| if: always() | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Check test results | |
| run: | | |
| echo "### Test Results Summary" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| setup_result="${{ needs.setup.result }}" | |
| ep_integrity_result="${{ needs.test-ep-integrity.result }}" | |
| wab_result="${{ needs.test-wab.result }}" | |
| wab_loader_result="${{ needs.test-wab-loader.result }}" | |
| packages_result="${{ needs.test-packages.result }}" | |
| plasmicpkgs_result="${{ needs.test-plasmicpkgs.result }}" | |
| e2e_result="${{ needs.test-e2e.result }}" | |
| echo "| Job | Result |" >> $GITHUB_STEP_SUMMARY | |
| echo "|-----|--------|" >> $GITHUB_STEP_SUMMARY | |
| echo "| Setup | ${setup_result} |" >> $GITHUB_STEP_SUMMARY | |
| echo "| EP Fork Integrity | ${ep_integrity_result} |" >> $GITHUB_STEP_SUMMARY | |
| echo "| WAB Tests | ${wab_result} |" >> $GITHUB_STEP_SUMMARY | |
| echo "| WAB Loader HTML | ${wab_loader_result} |" >> $GITHUB_STEP_SUMMARY | |
| echo "| SDK Packages | ${packages_result} |" >> $GITHUB_STEP_SUMMARY | |
| echo "| Plasmic Packages | ${plasmicpkgs_result} |" >> $GITHUB_STEP_SUMMARY | |
| echo "| E2E Tests | ${e2e_result} |" >> $GITHUB_STEP_SUMMARY | |
| # Fail if EP integrity check failed (EP customizations dropped) | |
| if [[ "${ep_integrity_result}" == "failure" ]]; then | |
| echo "" | |
| echo "EP fork integrity check failed — EP customizations may have been dropped." | |
| exit 1 | |
| fi | |
| # Fail if setup failed (required for WAB tests) | |
| if [[ "${setup_result}" == "failure" ]]; then | |
| echo "" | |
| echo "Setup job failed." | |
| exit 1 | |
| fi | |
| # Fail if any required job failed | |
| if [[ "${packages_result}" == "failure" ]] || [[ "${plasmicpkgs_result}" == "failure" ]]; then | |
| echo "" | |
| echo "One or more required test jobs failed." | |
| exit 1 | |
| fi | |
| # WAB tests are optional (can be skipped on PRs without label) | |
| if [[ "${wab_loader_result}" == "failure" ]]; then | |
| echo "" | |
| echo "WAB Loader HTML tests failed." | |
| exit 1 | |
| fi | |
| if [[ "${wab_result}" == "failure" ]]; then | |
| echo "" | |
| echo "WAB tests failed." | |
| exit 1 | |
| fi | |
| # E2E tests are optional (can be skipped on PRs without label) | |
| if [[ "${e2e_result}" == "failure" ]]; then | |
| echo "" | |
| echo "E2E tests failed." | |
| exit 1 | |
| fi | |
| echo "" | |
| echo "All tests passed!" |