Commit Graph
11 Commits
Author SHA1 Message Date
Oleg Isonen 8718feb465 test: simplify browser testing infrastructure (#6271)
## Summary

Unifies frontend testing around three intentional boundaries:

- Vitest Node projects for pure and server tests
- Vitest Browser Mode with Playwright/Chromium for DOM and component
tests
- Playwright Test for Builder end-to-end workflows

The Builder no longer uses jsdom. Ordinary E2E workflows use an
automatically managed isolated `page` fixture; explicit contexts remain
only for simultaneous identities and suite-scoped setup.

## Technical choices

- Split Builder tests into one Node project and independent browser
projects so each Chromium/Vite process has a bounded workload.
- Added shared Browser Mode configuration for the affected SDK React
packages.
- Preserve the Builder's production top-window bridge ownership; Browser
Mode uses explicit test-only installation seams.
- Centralized Playwright context options and kept action/navigation
timeouts bounded.
- Validate Playwright filters before Docker, migrations, browser
installation, or Builder builds start.
- Preserve the first failed E2E attempt's report, traces, screenshots,
and videos when CI retries a shard.
- Split static checks, typechecks, CLI tests, core package tests,
browser package tests, and Builder projects into parallel CI jobs with
five-minute hard ceilings.
- Distribute Builder E2E tests across ten isolated shards with two
workers; parallel suites create unique per-worker setup data.
- Reuse color contrast DOM/canvas samples so the exhaustive theme sweep
takes about four seconds instead of timing out at 30 seconds.
- The removed cost is jsdom behavior drift, oversized serial check jobs,
and unnecessary E2E startup for empty selections. Real browser startup
and E2E environment setup remain.

## Todo

- [x] Split Builder pure/server tests from browser/component tests.
- [x] Migrate Builder DOM tests from jsdom to Vitest Browser Mode.
- [x] Migrate affected SDK React DOM tests to the shared Browser Mode
setup.
- [x] Remove jsdom annotations, dependencies, and compatibility setup.
- [x] Replace ordinary manual E2E contexts with the isolated `page`
fixture.
- [x] Keep explicit contexts only for concurrent identities and
`beforeAll` setup.
- [x] Preserve setup authentication isolation from workflow pages.
- [x] Add bounded Playwright action and navigation timeouts.
- [x] Preserve first-attempt E2E failure evidence across CI retry.
- [x] Reject empty E2E selections before expensive environment setup.
- [x] Parallelize repository checks into bounded CI shards.
- [x] Isolate parallel E2E setup data across workers.
- [x] Remove the color contrast sweep bottleneck.
- [x] Update E2E contributor documentation.
- [x] Review product documentation impact; no user-facing product docs
are affected.
- [x] Run the full repository tests and typechecks.
- [x] Run formatting, lint, package-boundary, generated-file, and
fixture checks.
- [x] Complete final correctness and simplification review.

## Verification

- `pnpm --filter @webstudio-is/builder test`
- `pnpm -r typecheck`
- `pnpm lint`
- `pnpm check:package-boundaries`
- `pnpm check:generated-api`
- `pnpm check:generated-docs`
- `pnpm fixtures`
- Design-system: 222 tests pass locally.
- Builder: all seven Vitest projects pass locally.
- The formerly slow E2E shard passes locally in 1m55s.
- Full database-backed Builder E2E execution passes in CI.
- All CI jobs pass; the slowest completed in 4m58s.
- No fixture inputs/outputs or generated files changed.

Ref #6270
2026-08-31 17:17:28 +02:00
Oleg Isonen c3d2fa7fa3 feat: Render current page state on links in preview mode (#5810)
Closes https://github.com/webstudio-is/webstudio/issues/5207
2026-06-11 21:11:11 +02:00
Oleg Isonen 03f398d9b2 fix: Fix local link matching when query params are used (#5802)
Closes https://github.com/webstudio-is/webstudio/issues/5377


## Summary

Fixes local link matching so links are marked current only when the full
URL matches: pathname, search query, and hash.

## Changes

- Replaced duplicated Remix/React Router `Link` logic with a shared
`createLocalLink` helper.
- Switched from `NavLink` route-only active matching to explicit full
URL matching.
- Preserved exact `end`-style behavior while also requiring query/hash
equality.
- Kept hash-only links as native anchors so current search params are
not rewritten.
- Preserved browser-like behavior for `href=""` by resolving it to the
full current URL.
- Kept asset/external/protocol links as plain anchors.
- Added comments explaining why the shared local-link code exists and
why specific edge cases avoid router navigation.

## Tests

- Added URL matching unit tests for pathname/search/hash, case
sensitivity, trailing slash, empty href, hash href, and router-resolved
paths.
- Added React Router integration coverage for:
  - exact active/current matching
  - query/hash mismatches
  - active class and `aria-current`
  - hash-only links
  - empty links preserving search/hash
  - external/protocol/asset links
  - relative route links
  - `preventDefault`
  - pending navigation/render behavior
  - same-url resource updates
  - HTML embed navigation behavior

## Verification

- `pnpm --filter @webstudio-is/sdk-components-react test`
- `pnpm --filter @webstudio-is/sdk-components-react-router test`
- `pnpm --filter @webstudio-is/sdk-components-react typecheck`
- `pnpm --filter @webstudio-is/sdk-components-react-router typecheck`
- `pnpm --filter @webstudio-is/sdk-components-react-remix typecheck`
- `pnpm --filter @webstudio-is/sdk-components-react dts`
- `pnpm --filter @webstudio-is/sdk-components-react-router dts`
- `pnpm --filter @webstudio-is/sdk-components-react-remix dts`
2026-06-10 00:06:33 +02:00
Oleg Isonen bffc4597fe fix: Prevent outgoing page rerender during navigation (#5800)
**Description**

Prevents published pages from rerendering the outgoing generated page
during pending internal navigation.

React Router can rerender the current route while the next route loader
is pending. The generated `Page` was rendered directly inside that
route, so the entire outgoing page could rerender before the next page
appeared.

This adds a memoized `PageBoundary` keyed by `url`, so the generated
page only rerenders/remounts when the actual page URL changes. The SDK
context value is memoized by `resources`, preserving same-URL resource
updates without exposing the full page tree to unrelated
pending-navigation rerenders.

**Changes**
- Added `PageBoundary` to React Router and Remix/default HTML route
templates.
- Kept `key={url}` behavior for HTML Embed script reloads on dynamic
pages.
- Added regression tests for:
  - no outgoing page rerender while destination navigation is pending
  - same-URL resource changes still update generated page content
- Added Vitest setup for `sdk-components-react-router`.

**Verification**
```txt
pnpm --filter @webstudio-is/sdk-components-react-router test src/link.test.tsx
pnpm --filter @webstudio-is/sdk-components-react-router typecheck
pnpm --filter @webstudio-is/sdk-cli typecheck
```
2026-06-09 19:27:40 +02:00
Oleg Isonen 5318d4f7a6 fix: Make WebHook forms work on Brave browser (#5590)
Brave Shields blocks our bot protection mechanism (matchMedia
fingerprinting detection), causing form submissions to silently fail.

- Added getBraveErrorHtml() in SDK that returns error message HTML
- Form component renders the error when Brave is detected

See: https://github.com/brave/brave-browser/issues/46541
2026-01-28 00:30:48 +01:00
Bogdan Chadkin c14238ed5e experimental: override some tags with components (#5210)
Ref https://github.com/webstudio-is/webstudio/issues/3632

Remix client routing should still work even if we go full html. Here
added tag overrides to component generator so sdk could pass component
replacements for some tags like

- body -> Body
- a -> Link
- form -> RemixForm

See example here
https://github.com/webstudio-is/webstudio/pull/5210/files#diff-f2df0aea6543a33e57d770ff1791da886ab3dfd6dec37da4a41a611b9b13a19aR6
2025-05-19 13:20:15 +03:00
Bogdan Chadkin 0eea205bfc refactor: merge base and animation props with component metas (#5214)
Related https://github.com/webstudio-is/webstudio/pull/5211
2025-05-16 23:31:06 +03:00
Bogdan Chadkin ddc425cd40 fix: navigate hash urls natively (#4929)
Fixes https://github.com/webstudio-is/webstudio/issues/4830

Remix incorrectly navigates hashes and clear search params. Here fixed
this by using native `<a>` and tweaked the logic in builder.

Test navigating hashes (when search params are present) in builder and
on published site.
2025-03-02 11:05:37 +07:00
Bogdan Chadkin 1f48985a1c experimental: add docker template to CLI (#4744)
Here added first react-router template which additionally adds docker
support. For now only adds Dockerfile + .dockerignore. Will add support
for image transforms separately.

Mostly duplicated defaults template

- replaced remix packages with react-router ones
- replaced `return redirect()` with `throw redirect()`

The template for now is self contained. Will split base react-router
template when will add more integrations.
2025-01-19 17:04:31 +07:00
Ivan Starkov 42af921093 feat: Add head component (#4751)
## Description

Allows Head component

Hidden under `headSlotComponent` flag

Vercel fixture now have a HTMLRewriter example. Improves development.

## Todo In Next PR
- Head Title support
- Icons
- Allow reset `as` field

- [x] - BG is now white always
- [x] - It's shown as fixed element to not break layout 


##  Implementation details

This component has more priority above PageSettings meta tags
e.g. If some tag exists in PageSettings and in HeadSlot the HeadSlot
wins

## Steps for reproduction

Create HeadSlot

<img width="674" alt="image"
src="https://github.com/user-attachments/assets/b41f878e-b8fd-48b4-9204-5f079dc1719b"
/>

- [x] - Visit
https://webstudio-fixture-project-a-0su3o.wstd.work/head-tag
check server response.

<img width="433" alt="image"
src="https://github.com/user-attachments/assets/efb7de0d-c23e-4b0d-b775-170e6b61648e"
/>

See `og:title` is not duplicated.

- [x] - Check Elements Panel

<img width="565" alt="image"
src="https://github.com/user-attachments/assets/5742c3a8-47b1-4877-9b01-528eb3afffe5"
/>

See no duplicated. All tags exists.


- [x] - Click Home. 
See no meta tags are in Elements panel from `/head-tag` page

- [x] - Click back button

<img width="555" alt="image"
src="https://github.com/user-attachments/assets/2b166249-5fd0-4d0f-a451-ff3c1b4e62b5"
/>

See all meta is rendered and is not duplicated. 



## Code Review

- [ ] hi @kof, I need you to do
  - conceptual review (architecture, feature-correctness)
  - detailed review (read every line)
  - test it on preview

## Before requesting a review

- [ ] made a self-review
- [ ] added inline comments where things may be not obvious (the "why",
not "what")

## Before merging

- [ ] tested locally and on preview environment (preview dev login:
0000)
- [ ] updated [test
cases](https://github.com/webstudio-is/webstudio/blob/main/apps/builder/docs/test-cases.md)
document
- [ ] added tests
- [ ] if any new env variables are added, added them to `.env` file
2025-01-18 21:34:00 +03:00
Bogdan Chadkin 9aeb7a623f refactor: add sdk-components-react-router package (#4596)
This is 1:1 from sdk remix but with react-router imports to unlock
step-by-step migration to react-router v7
2025-01-11 23:05:44 +07:00