Skip to content

Component tests#5

Draft
opcode81 wants to merge 435 commits into
developfrom
component-tests
Draft

Component tests#5
opcode81 wants to merge 435 commits into
developfrom
component-tests

Conversation

@opcode81

Copy link
Copy Markdown

WIP; See the new memory

superalex and others added 30 commits June 17, 2026 14:52
* 🔧 Preserve atlas on zoom interaction 

Co-authored-by: Elena Torro <elenatorro@gmail.com>
- Convert .eleventy.js to eleventy.config.mjs (ESM) since
  @11ty/eleventy-plugin-rss@3.0.0 is ESM-only
- Replace search-index.json.njk with search-index.json.11ty.js
  to avoid async templateContent access in Nunjucks filters
- Update feed.njk to use new RSS plugin v3 filter names:
  rssLastUpdatedDate -> getNewestCollectionItemDate | dateToRfc3339
  rssDate -> dateToRfc3339
- Add 11ty.js to templateFormats for search index generation
Co-authored-by: Xavier Julian <xavier.julian@kaleidos.net>
Read PENPOT_TENANT env var (defaulting to "default") and embed it in
Redis Pub/Sub channel names as penpot.mcp.<tenant>.task.{req,res}.<id>.

This prevents cross-tenant interference when multiple environments share
a Redis instance, matching the backend convention
(e.g. penpot.rlimit.<tenant>.window.<name> in app.rpc.rlimit).

Co-authored-by: deepseek-v4-flash <deepseek-v4-flash@penpot.app>
Add wait-persisted and force-persist-and-wait to app.main.data.persistence,
removing 5 inline copies and 2 private helper functions across the codebase.

Replaced in:
- assets.cljs       -> dwp/force-persist-and-wait 400
- clipboard.cljs    -> dps/force-persist-and-wait 400
- versions.cljs     -> dwp/wait-persisted (3 call sites, dropped 2 priv fns)
- shape.cljs        -> dwp/wait-persisted 5000

Co-authored-by: deepseek-v4-flash <deepseek-v4-flash@penpot.app>
Fix the root cause in profile.cljs: remove the optimistic conj from
access-token-created and instead chain a fetch-access-tokens after the
create-access-token API call succeeds. This ensures all callers get a
fresh, server-consistent token list automatically.

Suggested-by: niwinz

Signed-off-by: kapilvus <kapil69265@gmail.com>
Co-authored-by: kapilvus <kapilvus@gmail.com>
…uble-click-guide

🐛 Fix double click not editing the guide
Alotor and others added 23 commits June 29, 2026 17:32
* ✨ Adds static dispatch safe stubs in tests

* 🐛 Fix shapesColors metadata key to match ColorShapeInfo

* 🐛 Fix CommentThread.remove rejecting the owner's own threads

* 🐛 Fix page.removeCommentThread throwing on a spurious Promise

* ✨ Implement ShapeBase.swapComponent in the plugin API

* ✨ Expose File.revn in the plugin API

* 🐛 Fix FileVersion.createdAt calling Luxon method on a js/Date

* 🐛 Fix plugin font/typography application to text and ranges

* 🐛 Default plugin overlay interaction position for non-manual types

* 🐛 Fix plugin interaction setters passing an id-only shape

* 🐛 Fix grid addColumnAtIndex rejecting valid track types

* 🐛 Expose libraryId on library color/typography/component proxies

* ✨ Implement LibraryTypography.setFont in the plugin API

* 🐛 Fix typography.applyToTextRange reading unexposed range bounds

* 🐛 Fix utils.geometry.center argument mismatch

* 🐛 Fix localStorage.removeItem calling getItem

* 🐛 Fix shape backgroundBlur proxy key casing

* 🐛 Report boolean shape type as 'boolean' in the plugin API

* 🐛 Return the resulting paths from plugin flatten

* 🐛 Make plugin z-order methods act on the target shape

* 🐛 Make is-variant-container? return a boolean

* ✨ Implement Group.isMask in the plugin API

* 🐛 Return a shape proxy from TextRange.shape

* 🐛 Return the duplicated set from TokenSet.duplicate

* 🐛 Fix theme addSet/removeSet reading set name with a keyword

* 🐛 Accept string fontFamilies token value in the plugin API

* 🐛 Fix combineAsVariants ignoring the passed component ids

* 🐛 Fix board removeRulerGuide ignoring its argument

* 🐛 Fix board guides setter schema and parser

* 🐛 Avoid 0-byte allocation when syncing empty grid tracks

* 🐛 Validate grid track indices in the plugin API

* 🐛 Return null for empty input in group() and centerShapes()

* 🐛 Return TokenTypographyValue[] from a typography token's resolvedValue

* 🐛 Return TokenShadowValue[] from a shadow token's resolvedValue

* 🐛 Return string[] from a fontFamilies token's resolvedValue

* 🐛 Clear mutually-exclusive reps when setting LibraryColor gradient/image

* 🐛 Add readonly tags to types, deprecate Image type

* 📚 Update plugins changelog
* 🐛 Fix undo frame position not undoing comments

* 🐛 Fix problem with hover capturing dragging event

* 🐛 Fix watch updates for comment bubbles

* 🐛 Fix "Maximum update depth" crash on SVG shape transforms

* 🐛 Fix comment geometry problems
…ot#10021)

* ♻️ Merge :thumbnails and :thumbnails-meta into single state key

♻️ Unify thumbnail refs in a single ref

🐛 Fix test

* ♻️ Update tests
…aying any error (penpot#10489)

* 🐛 Fix team invitations can be sent to existing members without displaying any error

* ✨ Add tests
* 🐛 Fix extra linebreak in Japense IME (MacOS)

* ♻️ Remove composing? from the state and query event instead
* 🐛 Fix dropdown shown Mixed Font Families for same family with different variant

* 🐛 Fix variants dropdown appearing blank on mixed variants but same family

* ✨ Add playwright test for mixed font families/variants
@opcode81 opcode81 force-pushed the component-tests branch 4 times, most recently from e5b6121 to 551fedd Compare July 2, 2026 09:43
opcode81 and others added 2 commits July 2, 2026 11:22
Introduce a framework for systematically testing Penpot component behaviour
(synchronisation/propagation, swaps, variant switches, nesting), plus a first
suite of cases built on it.

A test is expressed as a COMPOSITION OF OPERATIONS over a "situation" (an
in-memory file value plus named role bindings). Operations are reified as data
and composed by two combinators — `in-sequence` (threads the situation) and
`one-of`/`optional` (alternatives, enumerated into concrete variants). So one
written case stands for a whole matrix of variants, and coverage grows by
composition rather than by copying tests. Operations drive the REAL production
change pipeline, and event-operations dispatch the REAL workspace events and
await settlement, so the production watcher's automatic propagation is what is
exercised — the tests reflect genuine app behaviour, not a reimplementation.

Structure (frontend/test/frontend_tests/composable_tests/):
  - core            — the domain-agnostic engine: situation, the operation and
                      enumeration protocols, the combinators, and the runners.
  - comp/nodes      — the component operations (create/instantiate/reset, nesting,
                      swap, the variant ops, child add/remove/move, change, undo,
                      library sync).
  - comp/setups     — component-shaped starting configurations.
  - interpreter     — runs a case against the real frontend store: sync-ops apply
                      directly, event-ops dispatch real events and await
                      settlement (absorbing sync-file's delayed status RPC, which
                      would otherwise leak an error into subsequent tests).
  - comp/sync-test  — the cases (B-F, H, I, K, L, M).

This is test-only code with a single consumer — the frontend test suite (the
layer that runs the real app) — so it lives entirely under the frontend test
tree as .cljs, not under app/common.

The framework and its cases are documented in the project memory
frontend/composable-component-tests, added alongside.

Co-authored-by: Claude <noreply@anthropic.com>
`teardown-wasm-mocks!` unconditionally restored from the `originals` atom.
When run without a matching setup (double teardown, or `with-wasm-mocks*`
misused around an async test body), the snapshot is empty and every WASM API
function was `set!` to nil — permanently, for the remainder of the test run.
Any later code calling one of them (e.g. a leaked debounced resize-wasm-text
event firing during a subsequent test namespace) then crashed with
"initialized? is not a function".

Make the restore a no-op when there is nothing to restore.

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.