Skip to content

test: stabilize editor quality and e2e baseline#11

Merged
intel352 merged 4 commits into
masterfrom
impl/editor-quality-release
Apr 27, 2026
Merged

test: stabilize editor quality and e2e baseline#11
intel352 merged 4 commits into
masterfrom
impl/editor-quality-release

Conversation

@intel352
Copy link
Copy Markdown
Contributor

Summary

  • adds Node 22 pin and stable jsdom localStorage setup for Zustand persistence
  • fixes module-only export behavior covered by store tests
  • replaces placeholder Playwright tests with real editor workflow assertions
  • stabilizes full editor E2E suite

Verification

  • npm test
  • npm run test:e2e
  • npx tsc --noEmit
  • npm run build

Reviews

  • spec review requested E2E cleanup; fixed in 24607c2
  • antagonistic code review approved; low-order storage cleanup addressed in b762aa8

Copilot AI review requested due to automatic review settings April 27, 2026 06:19
@intel352 intel352 merged commit ce30048 into master Apr 27, 2026
6 checks passed
@intel352 intel352 deleted the impl/editor-quality-release branch April 27, 2026 06:22
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Stabilizes the editor’s unit/E2E test baseline across Node 22 + jsdom by hardening persistence/storage behavior and replacing placeholder Playwright checks with real editor workflow assertions.

Changes:

  • Add a deterministic localStorage mock (and related globals) for Vitest/jsdom to prevent persistence-related crashes.
  • Make workflow export resilient when workflows/triggers are omitted for module-only configs, and add regression tests.
  • Upgrade Playwright E2E coverage to assert real editor workflows (load, add node, edit config, save).

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/test/setup.ts Adds jsdom-safe localStorage + open mocks and clears storage between tests to stabilize persisted stores.
src/stores/workflowStore.ts Prevents Object.keys crashes when nodesToConfig() omits workflows/triggers.
src/stores/workflowStore.test.ts Adds a regression test for module-only import/export behavior.
src/stores/persistenceStorage.test.ts Adds tests ensuring the test environment provides a compatible localStorage and persisted stores can reset without throwing.
e2e/test-app/main.tsx Adds a shared default YAML fixture and exposes onSave output via document.body.dataset for E2E assertions.
e2e/editor.spec.ts Replaces placeholder E2E tests with concrete editor workflow assertions and updates YAML-line selection locator.
.nvmrc Pins local development Node version to 22 to match CI.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +24 to +33
expect(() => useWorkflowStore.getState().exportToConfig()).not.toThrow();
expect(useWorkflowStore.getState().exportToConfig()).toMatchObject({
modules: [
{
name: 'my-server',
type: 'http.server',
config: { address: ':9090' },
},
],
});
Copy link

Copilot AI Apr 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test currently uses toMatchObject({ modules: ... }), which will still pass even if exportToConfig() accidentally includes workflows: {} / triggers: {}. To actually protect the module-only export behavior, assert that those keys are absent (or undefined) in the exported config in addition to matching modules.

Copilot uses AI. Check for mistakes.
Comment thread e2e/editor.spec.ts
const initialCount = await nodes.count();

await page.getByPlaceholder('Filter modules...').fill('http.router');
await page.getByText('▶HTTP1').click();
Copy link

Copilot AI Apr 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The selector page.getByText('▶HTTP1') is brittle because it depends on the disclosure glyph and the filtered type count being rendered as contiguous text. Since the NodePalette header is composed of multiple elements (triangle + label + count), prefer a locator that targets the category label (e.g., locate the category row that contains text HTTP and click it) without hard-coding the glyph/count, to reduce E2E flakiness when UI text/layout changes.

Suggested change
await page.getByText('▶HTTP1').click();
await page.getByText('HTTP', { exact: true }).click();

Copilot uses AI. Check for mistakes.
Comment on lines +475 to 479
if (Object.keys(config.workflows ?? {}).length === 0 && Object.keys(importedWorkflows).length > 0) {
config.workflows = importedWorkflows;
}
if (Object.keys(config.triggers).length === 0 && Object.keys(importedTriggers).length > 0) {
if (Object.keys(config.triggers ?? {}).length === 0 && Object.keys(importedTriggers).length > 0) {
config.triggers = importedTriggers;
Copy link

Copilot AI Apr 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nodesToConfig() can omit workflows/triggers based on _originalKeys (see src/utils/serialization.ts:503-512), but it is typed as returning WorkflowConfig where those fields are required. Adding ?? {} here avoids a crash, but it also spreads the type/runtime mismatch into callers. Consider fixing the root cause by making workflows/triggers optional in WorkflowConfig (and tightening downstream handling) or by having nodesToConfig() always return them (possibly empty) and using _originalKeys only for YAML ordering.

Copilot uses AI. Check for mistakes.
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.

2 participants