feat: add local Safari testing via safaridriver#5131
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a custom Karma launcher to enable running the project’s unit tests locally in Safari via safaridriver, replacing the deprecated/broken third-party Safari launcher dependency.
Changes:
- Introduces
tests/karma.safari.cjs, a minimal W3C WebDriver client/launcher that spawnssafaridriverand navigates to the Karma URL. - Wires the custom launcher into the shared Karma config (
tests/karma.conf.base.cjs). - Removes
karma-safari-launcherfrom dependencies/lockfile.
Reviewed changes
Copilot reviewed 3 out of 4 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| tests/karma.safari.cjs | New custom Safari launcher using safaridriver + Node http. |
| tests/karma.conf.base.cjs | Replaces karma-safari-launcher plugin with the local Safari launcher. |
| package.json | Drops karma-safari-launcher dependency. |
| pnpm-lock.yaml | Removes karma-safari-launcher entries. |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
a2c04c4 to
4f300a5
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 4 changed files in this pull request and generated 2 comments.
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 4 changed files in this pull request and generated 1 comment.
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 5 out of 6 changed files in this pull request and generated 2 comments.
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
@copilot i think we should enable this by default to run alongside Chrome and Firefox, even if it’s more expensive to run on macOS in CI. We care that we don’t regress on WebKit/Safari so it’s worth it. |
Done in bd0debf — Safari is now enabled in CI on
|
|
@copilot Can you check and fix ci? |
Fixed in a7d2784. The CI failure had two root causes on cold macOS runners:
The |
|
@copilot Couple of lint errors to fix. See ci. |
Fixed in dab0d02 — two prettier formatting errors in
|
|
Seeing a lot ci fails @copilot. Do your thing, my good every so helpful little digital marvel. |
Fixed in ad409ca — two root causes identified from the Safari CI log:
|
|
@copilot can you review this again and fix any issues you find and any resolve any unresolved comments? |
Agent-Logs-Url: https://github.com/speced/respec/sessions/8e1b50fe-6001-4593-9c5d-d20618791bcb Co-authored-by: marcoscaceres <870154+marcoscaceres@users.noreply.github.com>
…I reliability Agent-Logs-Url: https://github.com/speced/respec/sessions/75aecc21-a5d1-4831-a107-5a4f42a262a9 Co-authored-by: marcoscaceres <870154+marcoscaceres@users.noreply.github.com>
Agent-Logs-Url: https://github.com/speced/respec/sessions/f825ab10-4ee2-427b-9176-637faabea744 Co-authored-by: marcoscaceres <870154+marcoscaceres@users.noreply.github.com>
…tReady Agent-Logs-Url: https://github.com/speced/respec/sessions/8f5dd784-fefd-442c-970b-ce6991b8fd8c Co-authored-by: marcoscaceres <870154+marcoscaceres@users.noreply.github.com>
…down Agent-Logs-Url: https://github.com/speced/respec/sessions/4c275e23-6d86-4c63-9268-4b625420bb32 Co-authored-by: marcoscaceres <870154+marcoscaceres@users.noreply.github.com>
In Safari, postMessage from opaque-origin srcdoc iframes may not be received (ev.source !== iframe.contentWindow). Add a 100ms polling loop that checks doc.respec.ready directly, racing the existing postMessage listener. Also: - Fix ev.source check to accept null/undefined (loose !=) - Wrap window.parent.postMessage in pubsubhub.js try/catch so postMessage failures don't propagate through pub() and disrupt runAll() - Suppress Promise.reject(err) unhandled rejection in iframe template so Safari doesn't cross-frame propagate it as undefined to jasmine Agent-Logs-Url: https://github.com/speced/respec/sessions/e996459b-6f02-4d6b-9ade-d9003140e5a4 Co-authored-by: marcoscaceres <870154+marcoscaceres@users.noreply.github.com>
Agent-Logs-Url: https://github.com/speced/respec/sessions/65cc375e-3e6f-43b8-9cf6-3e663ae1544c Co-authored-by: marcoscaceres <870154+marcoscaceres@users.noreply.github.com>
…ch errors Agent-Logs-Url: https://github.com/speced/respec/sessions/da22e939-2ed4-4370-9fc5-2450af0e5876 Co-authored-by: marcoscaceres <870154+marcoscaceres@users.noreply.github.com>
Instead of falling back to targetOrigin '*' (which leaks respecConfig data to any embedding parent), return early when parent.location.origin throws SecurityError. The polling fallback in SpecHelper.js handles test completion in Safari. Also guard ev.data access in msgHandler to prevent crashes from non-object message payloads.
Throw early if env var is set to a non-numeric value instead of silently passing NaN as the port argument to safaridriver.
…igin iframes; add port range validation Agent-Logs-Url: https://github.com/speced/respec/sessions/7457d32d-c547-4cd4-94fe-bab03a6343da Co-authored-by: marcoscaceres <870154+marcoscaceres@users.noreply.github.com>
…e for heading (#5207) Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
f6388e8 to
d5a21e6
Compare
Root cause: Safari ES module loader cannot resolve absolute paths from about:srcdoc documents (no origin to resolve against). Chrome and Firefox inherit the parent origin, but Safari does not. Fix: pass window.location.origin into the iframe script and build fully-qualified import URLs. Also add a base tag and unhandled rejection handler as defense in depth.
|
@copilot can you fix the CI issues? |
…; (Safari) Agent-Logs-Url: https://github.com/speced/respec/sessions/2c2ebc73-4a2f-4b6a-ace4-2dcfba2f7105 Co-authored-by: marcoscaceres <870154+marcoscaceres@users.noreply.github.com>
Fixed in 9a55b96. The 4 Safari-specific test failures had the same root cause: Safari returns
|
|
@copilot still seeing issues? |
The same Safari SecurityError bug that was fixed in tests/unit/SpecHelper.js was also present in tests/spec/SpecHelper.js. The msgHandler in makeRSDoc: - accessed ev.source.document which throws SecurityError in Safari for opaque-origin srcdoc iframes - accessed ev.data.topic without guarding against non-object payloads Changes: - Add settle() guard for single resolution - Replace unsafe ev.source.document check with try/catch - Guard ev.data with typeof check before reading .topic - Add 100ms polling fallback (same as unit SpecHelper) so tests complete even when postMessage isn't delivered reliably on Safari - Clear timeout and listeners on early resolution via doc.respec Agent-Logs-Url: https://github.com/speced/respec/sessions/d24e60b2-e396-49ad-a44b-7ccc2fc5e9da Co-authored-by: marcoscaceres <870154+marcoscaceres@users.noreply.github.com>
Fixed in 79aec16. The root cause was that The fix applies the same pattern: |
Enables
pnpm start --browser Safarifor local testing and adds Safari to CI.Problem
karma-safari-launcher@1.0.0(the published package) uses aredirect.htmlhack that modern Safari treats as a file download rather than opening it.@onslap/karma-safari-launcher(the replacement) depends onwd@1.xwhich requires a native build that doesn't compile on Node 24+.Solution
A minimal custom karma launcher (
tests/karma.safari.cjs) that talks directly tosafaridriverover W3C WebDriver HTTP protocol using Node's built-inhttpmodule. No new npm dependencies.Also fixes Safari-specific issues discovered during testing:
postMessagefrom srcdoc iframes: skip whenparent.location.originthrows SecurityError (Safari opaque-origin restriction) instead of falling back totargetOrigin: "*"ev.dataguard in message handler to prevent crashes from non-object payloadswaitReadyfor Safari whereev.source !== iframe.contentWindowtextContentinstead ofinnerTextfor highlight (Safari returns empty for closed<details>)parseInfoStringnull guard for Safari's marked tokenizerSetup (one-time per machine)
CI
Safari runs on
macos-latestin both PR and push workflows. macOS runners cost more than Linux but catching Safari-specific regressions is worth it.Closes #2894