Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
769d36a
goals and plan
jens-meisner Jun 18, 2026
6793f5f
storybook step1
jens-meisner Jun 18, 2026
29b3cfa
storybook step2
jens-meisner Jun 18, 2026
cb978d8
storybook step3
jens-meisner Jun 18, 2026
8b44411
storybook step4
jens-meisner Jun 18, 2026
7637a0c
storybook step4
jens-meisner Jun 18, 2026
11e88f4
storybook step5 - test1
jens-meisner Jun 18, 2026
ed497c2
storybook step5 - test3
jens-meisner Jun 18, 2026
a93b7dc
storybook step5 - test4
jens-meisner Jun 18, 2026
986a2ed
storybook step5 - test6
jens-meisner Jun 18, 2026
e126e20
storybook step5 - test10
jens-meisner Jun 18, 2026
7662a3d
storybook step5 - tests complete
jens-meisner Jun 18, 2026
2e131d6
storybook step8 - cleanup
jens-meisner Jun 18, 2026
d01162c
storybook step9
jens-meisner Jun 18, 2026
2135099
storybook step10
jens-meisner Jun 18, 2026
ace6976
storybook step11
jens-meisner Jun 18, 2026
6889d8d
plan tests refactoring
jens-meisner Jun 24, 2026
f1cbd0f
tests refactoring - phase 1
jens-meisner Jun 24, 2026
be4ab52
tests refactoring - phase 2
jens-meisner Jun 24, 2026
31a36b6
tests refactoring - added tests/constants package
jens-meisner Jun 24, 2026
b4def70
tests refactoring - phase 3
jens-meisner Jun 24, 2026
ddef8c0
tests refactoring - phase 4 - BBCode
jens-meisner Jun 24, 2026
67b2c06
tests refactoring - phase 4 - Blocklist
jens-meisner Jun 24, 2026
2c1c77a
tests refactoring - phase 4 - Blocklist specials
jens-meisner Jun 24, 2026
07adced
tests refactoring - phase 4 - added constants
jens-meisner Jun 24, 2026
fa35b25
tests refactoring - phase 4 - ContentLink
jens-meisner Jun 24, 2026
01ea023
tests refactoring - phase 4 - LinkBalloon
jens-meisner Jun 24, 2026
aca1929
tests refactoring - phase 4b - FontMapper
jens-meisner Jun 25, 2026
0f75c19
tests refactoring - phase 4b - PasteButton
jens-meisner Jun 25, 2026
64b21d6
tests refactoring - phase 4b - DragDrop
jens-meisner Jun 25, 2026
78d9535
tests refactoring - phase 4c - DocumentLists
jens-meisner Jun 25, 2026
b1dff1f
tests refactoring - phase 4c - Differencing
jens-meisner Jun 25, 2026
84b77b7
tests refactoring - phase 4c - Images
jens-meisner Jun 25, 2026
c2958e1
tests refactoring - phase 4d
jens-meisner Jun 25, 2026
44a9887
tests refactoring - phase 5 (cleanup)
jens-meisner Jun 25, 2026
cbca530
tests refactoring - phase 6
jens-meisner Jun 25, 2026
2d3d02a
tests refactoring - eliminated last "page.evaluate" call
jens-meisner Jun 25, 2026
e876991
tests refactoring - eliminated last "page.evaluate" call
jens-meisner Jun 25, 2026
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
126 changes: 126 additions & 0 deletions .github/workflows/deploy-storybook.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
name: "Deploy Storybook"

# Builds the Storybook integration-test package and publishes the static
# Storybook to GitHub Pages. The deployed Storybook is the same runtime the
# Playwright integration tests execute against (see tests/storybook and
# tests/playwright).
#
# To coexist with the existing GitHub Pages content (most notably the API
# documentation served from the Pages root), the Storybook is published into a
# dedicated `storybook/` subfolder of the `gh-pages` branch. Publishing uses
# `keep_files: true`, so sibling content (e.g. `docs/api/`) is left untouched.
# Resulting URL: https://coremedia.github.io/ckeditor-plugins/storybook/

on:
# Publish on every push to the main branch.
push:
branches:
- main
# Allow manual deployment from the Actions tab.
workflow_dispatch:

run-name: |
${{ github.workflow }}: ${{ github.ref_name }}

env:
# https://github.com/actions/runner-images/issues/70
NODE_OPTIONS: "--max_old_space_size=4096"

# Least-privilege defaults; the publish job opts into the permissions it needs.
permissions: {}

# Allow only one concurrent deployment, without cancelling in-progress runs, so
# an in-flight Pages deployment is allowed to complete.
concurrency:
group: "pages"
cancel-in-progress: false

jobs:
get-env:
name: "Get Environment"
uses: "./.github/workflows/env.yml"
get-engines:
name: "Get Engines"
uses: "./.github/workflows/get-engines.yml"
secrets: inherit
deploy:
name: "Build and Publish Storybook"
runs-on: ubuntu-latest
timeout-minutes: 20
needs:
- get-env
- get-engines
# Required to push the built Storybook to the `gh-pages` branch.
permissions:
contents: write
env:
nodeVersion: ${{ needs.get-engines.outputs.nodeVersion }}
pnpmVersion: ${{ needs.get-engines.outputs.pnpmVersion }}
npmHost: ${{ needs.get-env.outputs.npm-host }}
npmUrl: ${{ needs.get-env.outputs.npm-url }}
steps:
- id: checkout
name: Checkout
uses: actions/checkout@v5
- id: authorize
name: "NPM Authorization"
run: |
result=$(curl -s -H "Accept: application/json" -H "Content-Type:application/json" -X PUT --data '{"name": "${{ secrets.PLUGINS_NEXUS_USER }}", "password": "${{ secrets.PLUGINS_NEXUS_PASSWORD }}"}' "${{ env.npmUrl }}/-/user/org.couchdb.user:${{ secrets.PLUGINS_NEXUS_USER }}" | jq --raw-output .token)
# Ensure, the token is not exposed in output.
echo "::add-mask::${result}"
echo "NODE_AUTH_TOKEN=${result}" >> $GITHUB_ENV
- id: initNpmConfiguration
name: "Initialize NPM Configuration"
run: |
npmHost="${{ env.npmHost }}"
npmUrl="${{ env.npmUrl }}"
npmAuthToken="${{ env.NODE_AUTH_TOKEN }}"

echo "//${npmHost}/:_authToken=${npmAuthToken}" >> .npmrc
echo "@coremedia:registry=${npmUrl}" >> .npmrc
echo "@coremedia-internal:registry=${npmUrl}" >> .npmrc
# We must not commit this change.
git update-index --assume-unchanged .npmrc
- id: installPnpm
name: "Install: Use PNPM ${{ env.pnpmVersion }}"
uses: pnpm/action-setup@v5
with:
version: ${{ env.pnpmVersion }}
run_install: false
- id: installNodeJs
name: "Install: Use Node.js ${{ env.nodeVersion }}"
uses: actions/setup-node@v5
with:
node-version: ${{ env.nodeVersion }}
cache: "pnpm"
- id: install
name: Install
run: |
pnpm install --frozen-lockfile
- name: Create env file
run: |
touch .env
echo CKEDITOR_LICENSE_KEY=${{ secrets.CKEDITOR_LICENSE }}>> .env
- id: build
name: "Build Workspace"
run: |
pnpm -r build
- id: buildStorybook
name: "Build Storybook"
env:
CKEDITOR_LICENSE_KEY: ${{ secrets.CKEDITOR_LICENSE }}
run: |
pnpm --filter "@coremedia/ckeditor5-storybook-itest" run build-storybook
- id: publish
name: "Publish Storybook to GitHub Pages"
uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: tests/storybook/build/storybook
# Publish into a subfolder so the existing Pages content (e.g. the API
# docs at the Pages root) is preserved.
destination_dir: storybook
keep_files: true
user_name: "github-actions[bot]"
user_email: "github-actions[bot]@users.noreply.github.com"
commit_message: "docs(storybook): deploy ${{ github.sha }}"
36 changes: 36 additions & 0 deletions GOALS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Goals

## Objective

Create a new Storybook package and use it as the runtime target for Playwright tests.

## Current State

- Playwright tests are located in `tests/playwright`.
- Playwright currently runs against the app in `app`.
- The Playwright app contains wrappers used to set up test scenarios, including locator-based wrappers and JS-handle wrappers.
- JS-handle wrappers currently include type workarounds for missing importable Playwright internals (for example `PageFunctionOn`).

## Target State

- Introduce a dedicated Storybook package for UI test scenarios.
- Configure Playwright tests in `tests/playwright` to run against Storybook instead of the `app` target.
- Provide a dedicated Storybook story for each Playwright test case.
- Move JS-wrapper functionality from Playwright test code into the Storybook package as reusable story setup utilities.
- Remove `JSWrapper`-based and other JS-handle wrappers; keep locator-based wrappers where they provide value.
- Eliminate JS-wrapper-specific type workarounds (for example local replacements for `PageFunctionOn`).
- Deploy the Storybook package to GitHub Pages.
- Update `README.md` at the end to document the final Storybook package and Playwright integration workflow.

## Success Criteria

- A Storybook package exists and can be started in a stable way for tests.
- Playwright uses the Storybook URL/runtime as its test target.
- Existing Playwright test location (`tests/playwright`) remains unchanged.
- Each Playwright test has a dedicated corresponding Storybook story.
- Story setup for tests is driven by Storybook-side utilities migrated from wrapper functionality.
- Test scenario setup behavior remains intact after removing JS-handle wrappers.
- Locator-based wrappers continue to be supported where appropriate.
- No custom type shims remain that only exist to support `JSWrapper` internals.
- Storybook is deployed and reachable via GitHub Pages.
- `README.md` is updated at the end with the finalized Storybook/test setup documentation.
93 changes: 93 additions & 0 deletions IMPLEMENTATION_PLAN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# Storybook + Playwright Implementation Plan

This plan describes how to implement the goals defined in `GOALS.md` step by step.

## 1. Create Storybook package skeleton

- [x] Add a new workspace package for Storybook in `tests/storybook`.
- [x] Register `tests/storybook` in `pnpm-workspace.yaml`.
- [x] Add all new Storybook dependencies via pnpm in the `tests/storybook` package and ensure workspace wiring is updated accordingly.
- [x] Configure Storybook build and dev scripts.
- [x] Ensure the package can run locally and build in CI.

## 2. Define Storybook test runtime contract

- [x] Define a stable story URL strategy that Playwright can target.
- [x] Define story args/parameters for scenario setup input.
- [x] Provide a shared helper module in Storybook for scenario initialization.

## 3. Migrate JS-wrapper functionality into Storybook utilities

- [x] Inventory all `JSWrapper`-based wrappers used by Playwright tests.
- [x] Move the setup logic into Storybook-side utilities (no Playwright JSHandle wrappers).
- [x] Replace `JSWrapper`-specific type shims/workarounds (including `PageFunctionOn`-style local types) with Storybook-side implementation.

## 4. Keep and align locator-based access patterns

- [x] Keep locator-based wrappers/helpers where they add clarity and value.
- [x] Align locator APIs with Storybook story structure and stable selectors.

## 5. Migrate Playwright tests one by one

- [x] Create a migration checklist of all test files in `tests/playwright/test`.
- [x] Build real editor factories (richtext + bbcode) in the Storybook package, ported from `app/src/editors`.
- [x] Pick one test file, create/migrate the corresponding Storybook story setup, and switch only that test to Storybook runtime.
- [x] Validate that migrated test file passes before starting the next file.
- [x] Repeat until every Playwright test file is migrated.
- [x] Track completion per test file by checking off each migrated item.

### Per-test migration checklist

- [x] `HelloEditor.test.ts` (richtext base scenario)
- [x] `Application.test.ts`
- [x] `BBCode.test.ts` (bbcode base scenario)
- [x] `ContentLink.test.ts`
- [x] `LinkBalloon.test.ts`
- [x] `LinkUserInteraction.test.ts`
- [x] `Blocklist.test.ts`
- [x] `BlocklistCollapsed.test.ts`
- [x] `BlocklistExpandedToolbar.test.ts`
- [x] `BlocklistExpandedKeyboard.test.ts`
- [x] `Differencing.test.ts`
- [x] `DocumentLists.test.ts`
- [x] `DragDrop.test.ts`
- [x] `FontMapper.test.ts`
- [x] `Images.test.ts`
- [x] `PasteButton.test.ts`

## 6. Create and refine stories for migrated scenarios

- [x] Ensure each migrated test has a dedicated story/scenario entry in Storybook.
- [x] Wire each migrated story to the Storybook setup utilities.
- [x] Ensure scenario behavior matches current tests.

## 7. Switch Playwright runtime target to Storybook

- [x] Update Playwright environment/config to point to Storybook URL instead of `app`.
- [x] Update web server startup command in Playwright config to run Storybook.
- [x] Keep test location under `tests/playwright` unchanged.

## 8. Remove obsolete JS-handle wrappers

- [x] Remove `tests/playwright/test/wrappers/JSWrapper.ts`.
- [x] Remove wrappers that only exist for JS-handle access.
- [x] Keep locator-based wrappers that remain useful.
- [x] Clean imports/usages and delete dead code.

## 9. Add GitHub Pages deployment for Storybook

- [x] Add/adjust CI workflow to build and publish Storybook to GitHub Pages.
- [x] Ensure deployment uses the correct base path for this repository.
- [x] Verify deployed Storybook is reachable.

## 10. Hardening and parity checks

- [x] Run lint/build/tests for affected packages.
- [x] Fix regressions in story setup and Playwright execution.
- [x] Confirm all success criteria from `GOALS.md` are met.

## 11. Final documentation update

- [x] Update `README_STORYBOOK` at the end with finalized Storybook package usage.
- [x] Document how Playwright targets Storybook and how stories map to tests.
- [x] Document GitHub Pages URL/deployment behavior.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,8 @@ implements the described behavior.
## See Also

* **[GitHub Pages][gp:ckeditor-plugins]:** These pages on GitHub Pages.
* **[Storybook][gp:storybook]:** Interactive Storybook of the integration-test
scenarios on GitHub Pages (see [`tests/storybook`](./tests/storybook/README.md)).
* **[Walk-Through Examples](./examples/README.md):** Some step-by-step guides
for customizing CKEditor 5.
* **[Development](./DEVELOPMENT.md):** Hints for developing within this
Expand Down Expand Up @@ -250,3 +252,5 @@ implements the described behavior.
[CoreMedia CMS]: <https://www.coremedia.com/> "Best-of-Breed Digital Experience Platform CoreMedia"

[gp:ckeditor-plugins]: <https://coremedia.github.io/ckeditor-plugins/> "CoreMedia CKEditor 5 Plugins – GitHub Pages"

[gp:storybook]: <https://coremedia.github.io/ckeditor-plugins/storybook/> "CoreMedia CKEditor 5 Plugins – Storybook"
Loading
Loading