|
| 1 | +--- |
| 2 | +name: bpmn-browser-testing |
| 3 | +description: > |
| 4 | + Interact with the BPMN modeler webview running in a browser using Playwright MCP tools. |
| 5 | + Use this skill whenever the user asks to test, inspect, or interact with the BPMN modeler |
| 6 | + in a browser — including adding/modifying BPMN elements, checking the properties panel, |
| 7 | + verifying UI behavior, or debugging the webview. Also trigger when the user mentions |
| 8 | + "serve:bpmn-webview", "open the modeler in a browser", "add a task/event/gateway", |
| 9 | + "check the properties panel", or any visual/interactive testing of the BPMN webview. |
| 10 | +--- |
| 11 | + |
| 12 | +# BPMN Browser Testing with Playwright |
| 13 | + |
| 14 | +This skill explains how to interact with the bpmn-js modeler webview in a real browser |
| 15 | +using the Playwright MCP plugin. The webview is an SVG-based BPMN editor built on |
| 16 | +[bpmn-js](https://github.com/bpmn-io/bpmn-js) with a Camunda properties panel. |
| 17 | + |
| 18 | +## Starting the dev server |
| 19 | + |
| 20 | +```bash |
| 21 | +corepack yarn serve:bpmn-webview |
| 22 | +``` |
| 23 | + |
| 24 | +This runs Vite on `http://localhost:5173`. In dev mode (`NODE_ENV=development`), the |
| 25 | +webview skips the VS Code clipboard bridge and uses native browser clipboard instead. |
| 26 | + |
| 27 | +## Page structure |
| 28 | + |
| 29 | +The webview DOM has three main areas: |
| 30 | + |
| 31 | +| Selector | Area | Notes | |
| 32 | +|----------------------------|-------------------|----------------------------------------------| |
| 33 | +| `#js-canvas` | bpmn-js canvas | SVG-based — mostly opaque to accessibility | |
| 34 | +| `#js-properties-panel` | Properties panel | Standard HTML — fully accessible via snapshot | |
| 35 | +| `#js-panel-resizer` | Resizer handle | Between canvas and panel | |
| 36 | + |
| 37 | +The palette (left toolbar) and context pad (icons around selected elements) are rendered |
| 38 | +inside the canvas container but are accessible via `getByTitle()`. |
| 39 | + |
| 40 | +## Key interaction patterns |
| 41 | + |
| 42 | +### Placing elements from the palette (click-then-click) |
| 43 | + |
| 44 | +bpmn-js palette entries do NOT work with standard HTML drag-and-drop. Use a two-step |
| 45 | +click pattern: |
| 46 | + |
| 47 | +1. **Click the palette entry** to activate "create mode" |
| 48 | +2. **Click on the canvas** to place the element |
| 49 | + |
| 50 | +```js |
| 51 | +// Step 1: activate create mode |
| 52 | +await page.getByTitle('Create task').click(); |
| 53 | +// Step 2: click on the canvas to place |
| 54 | +await page.mouse.click(250, 350); |
| 55 | +``` |
| 56 | + |
| 57 | +Drag-and-drop via `element.dragTo()` or manual `mouse.down/move/up` does NOT work |
| 58 | +reliably because bpmn-js uses a custom drag implementation on an SVG canvas. |
| 59 | + |
| 60 | +### Using the context pad |
| 61 | + |
| 62 | +After placing/selecting an element, bpmn-js shows a context pad with action icons. |
| 63 | +These ARE visible in accessibility snapshots via their `title` attributes: |
| 64 | + |
| 65 | +- `Append end event`, `Append gateway`, `Append task`, `Append intermediate/boundary event` |
| 66 | +- `Change element` — opens the type selection popup |
| 67 | +- `Delete`, `Set color`, `Connect to other element` |
| 68 | +- `Add text annotation`, `Append element` |
| 69 | + |
| 70 | +Use `browser_snapshot` to discover the available context pad entries and their refs, |
| 71 | +then click them directly. |
| 72 | + |
| 73 | +### Changing element type |
| 74 | + |
| 75 | +To convert a generic task to a specific type (e.g., Service Task): |
| 76 | + |
| 77 | +1. Select the element (click on it) |
| 78 | +2. Click `Change element` in the context pad |
| 79 | +3. A popup appears with a searchable list — click the desired type |
| 80 | + |
| 81 | +``` |
| 82 | +snapshot → find ref for "Change element" → click it |
| 83 | +snapshot → find ref for "Service task" → click it |
| 84 | +``` |
| 85 | + |
| 86 | +The properties panel updates immediately to show type-specific sections. |
| 87 | + |
| 88 | +### Reading and interacting with the properties panel |
| 89 | + |
| 90 | +The properties panel (`#js-properties-panel`) is standard HTML and fully accessible. |
| 91 | +Use `browser_snapshot` to read its state — section headers, form fields, buttons. |
| 92 | + |
| 93 | +Common panel sections for a Service Task: |
| 94 | +- **General** — Name, ID |
| 95 | +- **Task definition** — Job type, retries |
| 96 | +- **Input mapping** / **Output mapping** |
| 97 | +- **Headers** |
| 98 | +- **Execution listeners** |
| 99 | +- **Extension properties** |
| 100 | +- **Example data** |
| 101 | + |
| 102 | +Sections can be expanded/collapsed via "Toggle section" buttons. |
| 103 | + |
| 104 | +### Selecting existing elements |
| 105 | + |
| 106 | +Elements on the SVG canvas are not directly addressable via accessibility snapshots. |
| 107 | +To select an existing element, use coordinate-based clicking: |
| 108 | + |
| 109 | +```js |
| 110 | +// Click at known canvas coordinates |
| 111 | +await page.mouse.click(x, y); |
| 112 | +``` |
| 113 | + |
| 114 | +Alternatively, use `browser_take_screenshot` to visually locate elements, then click |
| 115 | +at the appropriate coordinates. |
| 116 | + |
| 117 | +## When to use screenshots vs snapshots |
| 118 | + |
| 119 | +| Tool | Best for | |
| 120 | +|-------------------------|-------------------------------------------------------| |
| 121 | +| `browser_snapshot` | Properties panel, palette, context pad, popups | |
| 122 | +| `browser_take_screenshot` | Canvas elements (tasks, events, gateways, flows) | |
| 123 | + |
| 124 | +The SVG canvas renders very little in the accessibility tree. Always use screenshots |
| 125 | +to verify what's actually on the canvas (element positions, connections, labels). |
| 126 | +Use snapshots for interacting with HTML-based UI (palette, panels, popups). |
| 127 | + |
| 128 | +## Modeler API (not directly accessible) |
| 129 | + |
| 130 | +The `BpmnModeler` class instance is NOT exposed on `window`, so you cannot call the |
| 131 | +bpmn-js API via `page.evaluate()`. All interaction must go through the Playwright UI |
| 132 | +tools (click, snapshot, screenshot). |
| 133 | + |
| 134 | +## Console output |
| 135 | + |
| 136 | +Expect these console messages in dev mode — they are not errors in your workflow: |
| 137 | +- `[ERROR] Theme link element not found.` — Normal in browser (theme link is injected by VS Code) |
| 138 | +- `[LOG] Missing translation [en]: ...` — Translation keys not yet added for the current locale |
| 139 | +- `[LOG] development` — Confirms dev mode is active |
| 140 | + |
| 141 | +## Common recipes |
| 142 | + |
| 143 | +### Add a Service Task and configure it |
| 144 | + |
| 145 | +``` |
| 146 | +1. browser_snapshot → find "Create task" ref → click it |
| 147 | +2. browser_run_code → page.mouse.click(250, 350) to place on canvas |
| 148 | +3. browser_snapshot → find "Change element" ref → click it |
| 149 | +4. browser_snapshot → find "Service task" ref → click it |
| 150 | +5. browser_snapshot → expand "Task definition" → fill in job type |
| 151 | +``` |
| 152 | + |
| 153 | +### Connect two elements |
| 154 | + |
| 155 | +``` |
| 156 | +1. Click source element on canvas |
| 157 | +2. browser_snapshot → find "Connect to other element" → click it |
| 158 | +3. Click target element on canvas |
| 159 | +``` |
| 160 | + |
| 161 | +### Verify element was created |
| 162 | + |
| 163 | +``` |
| 164 | +1. browser_take_screenshot → visually confirm element on canvas |
| 165 | +2. browser_snapshot → check properties panel shows correct type and sections |
| 166 | +``` |
| 167 | + |
| 168 | +## Troubleshooting |
| 169 | + |
| 170 | +- **Element not placed after palette click**: Make sure you click on the canvas area |
| 171 | + (not the properties panel or palette). The canvas is `#js-canvas`, roughly the center |
| 172 | + of the viewport excluding the left palette bar and right properties panel. |
| 173 | +- **Context pad not showing**: The element might not be selected. Click directly on |
| 174 | + the element's position on the canvas. |
| 175 | +- **Properties panel empty**: Click somewhere on the canvas background to deselect, |
| 176 | + then click the element again. |
| 177 | + |
| 178 | +## Reference |
| 179 | + |
| 180 | +For deeper details on the webview architecture, read: |
| 181 | +- `apps/bpmn-webview/src/main.ts` — Entry point and message routing |
| 182 | +- `apps/bpmn-webview/src/app/modeler.ts` — BpmnModeler class (C7/C8 engine setup) |
| 183 | +- `apps/bpmn-webview/index.html` — DOM structure |
0 commit comments