@omega.js/desktop 0.52.0 → 0.54.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +53 -48
- package/dist/assets/css/core/_initialize.scss +1 -1
- package/dist/assets/js/core/app-shell.js +14 -15
- package/dist/assets/themes/_template/_theme.js +6 -6
- package/dist/assets/themes/base/_includes/global/sections/account.html +4 -4
- package/dist/assets/themes/base/_includes/global/sections/app-sidebar.html +5 -5
- package/dist/assets/themes/base/_layouts/frontend/pages/account/index.html +3 -3
- package/dist/assets/themes/base/_layouts/frontend/pages/alternatives/index.html +1 -1
- package/dist/assets/themes/base/_layouts/frontend/pages/blog/tags/tag.html +1 -1
- package/dist/assets/themes/base/_layouts/frontend/pages/payment/confirmation.html +1 -1
- package/dist/assets/themes/base/_sections/marketing/newsletter-cta/section.js +2 -3
- package/dist/assets/themes/base/_sections/verts/unit/section.html +1 -1
- package/dist/assets/themes/base/_sections/verts/unit/section.js +3 -4
- package/dist/assets/themes/base/_theme.js +4 -3
- package/dist/assets/themes/bootstrap/_theme.js +2 -2
- package/dist/assets/themes/bootstrap/overrides/_links.scss +1 -1
- package/dist/assets/themes/classy/_theme.js +8 -6
- package/dist/assets/themes/classy/css/marketing/_sections.scss +1 -2
- package/dist/assets/themes/classy/js/hero-demo-form.js +3 -2
- package/dist/assets/themes/neobrutalism/_theme.js +5 -5
- package/dist/assets/themes/neobrutalism/js/pages/test/libraries/layers/index.js +1 -1
- package/dist/assets/themes/newsflash/_theme.js +6 -6
- package/dist/assets/themes/newsflash/js/pages/test/libraries/layers/index.js +1 -1
- package/dist/build.js +87 -111
- package/dist/cli-run.js +4 -1
- package/dist/cli.js +3 -3
- package/dist/commands/build.js +2 -2
- package/dist/commands/cdp/capture.js +2 -2
- package/dist/commands/cdp/client.js +1 -1
- package/dist/commands/cdp/quit.js +2 -2
- package/dist/commands/cdp/relaunch.js +2 -2
- package/dist/commands/cdp/theme.js +1 -1
- package/dist/commands/cdp.js +1 -1
- package/dist/commands/clean.js +4 -5
- package/dist/commands/deploy.js +4 -4
- package/dist/commands/dev.js +25 -0
- package/dist/commands/finalize-release.js +4 -4
- package/dist/commands/launch.js +2 -2
- package/dist/commands/lib/deploy-precheck.js +3 -3
- package/dist/commands/lib/ensure-target.js +18 -23
- package/dist/commands/lib/migrate.js +17 -0
- package/dist/commands/logs.js +1 -1
- package/dist/commands/package.js +2 -2
- package/dist/commands/publish.js +2 -2
- package/dist/commands/release.js +4 -4
- package/dist/commands/runner.js +11 -11
- package/dist/commands/sign-windows.js +5 -5
- package/dist/commands/test.js +8 -8
- package/dist/commands/update.js +7 -6
- package/dist/commands/validate-certs.js +4 -4
- package/dist/commands/version.js +3 -3
- package/dist/defaults/.github/workflows/build.yml +18 -18
- package/dist/defaults/_.gitignore +0 -2
- package/dist/defaults/_mas/README.md +3 -3
- package/dist/defaults/config/certs/README.md +1 -1
- package/dist/defaults/config/omega.json5 +43 -43
- package/dist/defaults/docs/README.md +3 -3
- package/dist/defaults/gulpfile.js +1 -1
- package/dist/defaults/hooks/build/post.js +2 -2
- package/dist/defaults/hooks/build/pre.js +2 -2
- package/dist/defaults/hooks/deploy/pre.js +1 -1
- package/dist/defaults/hooks/notarize/post.js +2 -2
- package/dist/defaults/hooks/release/post.js +2 -2
- package/dist/defaults/hooks/release/pre.js +2 -2
- package/dist/defaults/src/assets/js/components/about/index.js +3 -5
- package/dist/defaults/src/assets/js/components/main/index.js +3 -5
- package/dist/defaults/src/assets/js/components/settings/index.js +3 -5
- package/dist/defaults/src/assets/scss/pages/about.scss +1 -1
- package/dist/defaults/src/assets/scss/pages/main.scss +1 -1
- package/dist/defaults/src/assets/scss/pages/settings.scss +1 -1
- package/dist/defaults/src/integrations/context-menu/index.js +13 -13
- package/dist/defaults/src/integrations/menu/index.js +8 -8
- package/dist/defaults/src/integrations/tray/index.js +12 -12
- package/dist/defaults/src/main.js +5 -7
- package/dist/defaults/src/preload.js +4 -6
- package/dist/defaults/test/README.md +5 -5
- package/dist/defaults/test/_init.js +1 -1
- package/dist/gulp/main.js +9 -10
- package/dist/gulp/tasks/audit.js +11 -14
- package/dist/gulp/tasks/build-config.js +8 -8
- package/dist/gulp/tasks/bundle.js +16 -16
- package/dist/gulp/tasks/defaults.js +3 -3
- package/dist/gulp/tasks/distribute.js +2 -2
- package/dist/gulp/tasks/html.js +9 -9
- package/dist/gulp/tasks/package-quick.js +3 -3
- package/dist/gulp/tasks/package.js +3 -3
- package/dist/gulp/tasks/release.js +3 -3
- package/dist/gulp/tasks/sass.js +6 -6
- package/dist/gulp/tasks/serve.js +4 -4
- package/dist/hooks/notarize-artifacts.js +1 -1
- package/dist/hooks/notarize.js +1 -1
- package/dist/index.js +5 -8
- package/dist/lib/_environment-mixin.js +50 -0
- package/dist/lib/_lifecycle-mixin.js +45 -0
- package/dist/lib/analytics.js +33 -35
- package/dist/lib/app-state.js +14 -14
- package/dist/lib/auth-flow.js +18 -18
- package/dist/lib/auth-persistence.js +12 -12
- package/dist/lib/auth.js +421 -0
- package/dist/lib/auto-updater.js +49 -49
- package/dist/lib/context-menu.js +13 -13
- package/dist/lib/context.js +19 -19
- package/dist/lib/deep-link.js +34 -34
- package/dist/lib/fontawesome.js +5 -5
- package/dist/lib/ipc.js +4 -4
- package/dist/lib/menu.js +25 -25
- package/dist/lib/protocol.js +5 -5
- package/dist/lib/remote-config.js +22 -22
- package/dist/lib/remote-scripts.js +21 -21
- package/dist/lib/restart-manager/index.js +29 -29
- package/dist/lib/restart-manager/install.js +1 -1
- package/dist/lib/restart-manager/protocol.js +1 -1
- package/dist/lib/sign-helpers/exec-with-limit.js +1 -1
- package/dist/lib/sign-helpers/sign-events.js +1 -1
- package/dist/lib/startup.js +18 -13
- package/dist/lib/storage.js +10 -10
- package/dist/lib/templating.js +16 -16
- package/dist/lib/theme.js +10 -10
- package/dist/lib/tray.js +27 -27
- package/dist/lib/usage.js +11 -11
- package/dist/lib/window-manager.js +26 -26
- package/dist/main.js +399 -483
- package/dist/preload.js +236 -176
- package/dist/renderer.js +417 -391
- package/dist/test/fixtures/consumer-app/config/omega.json5 +1 -1
- package/dist/test/fixtures/consumer-app/src/assets/js/components/main/index.js +8 -11
- package/dist/test/fixtures/consumer-app/src/main.js +5 -7
- package/dist/test/fixtures/consumer-app/src/preload.js +2 -2
- package/dist/test/harness/boot-entry.js +22 -20
- package/dist/test/harness/main-entry.js +31 -30
- package/dist/test/harness/renderer-entry.js +5 -5
- package/dist/test/harness/renderer-preload.js +137 -141
- package/dist/test/index.js +10 -10
- package/dist/test/runner.js +2 -2
- package/dist/test/runners/boot.js +7 -6
- package/dist/test/runners/electron.js +3 -2
- package/dist/test/runners/render-event.js +2 -2
- package/dist/test/suites/boot/consumer-app-boots.test.js +57 -26
- package/dist/test/suites/boot/restart-manager.test.js +2 -2
- package/dist/test/suites/boot/storage-bundled.test.js +5 -5
- package/dist/test/suites/boot/theme.test.js +13 -13
- package/dist/test/suites/build/audit.test.js +21 -8
- package/dist/test/suites/build/auth-persistence-resolve.test.js +6 -6
- package/dist/test/suites/build/boot-fixture.test.js +2 -2
- package/dist/test/suites/build/boot-runner-timeout.test.js +6 -5
- package/dist/test/suites/build/brand-scss.test.js +1 -1
- package/dist/test/suites/build/build-json-bake.test.js +1 -1
- package/dist/test/suites/build/build-workflow-jobs.test.js +2 -2
- package/dist/test/suites/build/cli.test.js +30 -2
- package/dist/test/suites/build/config-schema.test.js +5 -5
- package/dist/test/suites/build/defaults-em-dash.test.js +22 -0
- package/dist/test/suites/build/defaults-scaffold.test.js +21 -7
- package/dist/test/suites/build/deploy-direct.test.js +7 -5
- package/dist/test/suites/build/deploy-dispatch.test.js +2 -1
- package/dist/test/suites/build/deploy-hook.test.js +7 -5
- package/dist/test/suites/build/dev-verb.test.js +67 -0
- package/dist/test/suites/build/ensure-target.test.js +13 -5
- package/dist/test/suites/build/env-delivery.test.js +2 -2
- package/dist/test/suites/build/esm-only-dependency.test.js +2 -2
- package/dist/test/suites/build/exports.test.js +9 -8
- package/dist/test/suites/build/get-config.test.js +4 -4
- package/dist/test/suites/build/manifest-deps.test.js +1 -1
- package/dist/test/suites/build/merge-line-files.test.js +7 -7
- package/dist/test/suites/build/migrate.test.js +29 -0
- package/dist/test/suites/build/omega-shell.test.js +34 -2
- package/dist/test/suites/build/omega.test.js +350 -0
- package/dist/test/suites/build/project-scripts-deps.test.js +6 -10
- package/dist/test/suites/build/renderer-auth-bridge.test.js +211 -78
- package/dist/test/suites/build/runner-env-write.test.js +73 -0
- package/dist/test/suites/build/runner.test.js +11 -10
- package/dist/test/suites/build/sentry.test.js +2 -2
- package/dist/test/suites/build/setup-scripts.test.js +27 -0
- package/dist/test/suites/build/sign-windows-e2e.test.js +2 -2
- package/dist/test/suites/build/templating.test.js +3 -3
- package/dist/test/suites/build/test-stealth.test.js +7 -9
- package/dist/test/suites/build/url-helpers.test.js +55 -56
- package/dist/test/suites/build/validate-config.test.js +15 -4
- package/dist/test/suites/build/verb-logs.test.js +20 -0
- package/dist/test/suites/build/wave5-pins.test.js +2 -2
- package/dist/test/suites/main/analytics.test.js +59 -59
- package/dist/test/suites/main/app-state.test.js +66 -66
- package/dist/test/suites/main/auth-flow.test.js +41 -41
- package/dist/test/suites/main/auth-persistence.test.js +54 -43
- package/dist/test/suites/main/{client-bridge.integration.test.js → auth.integration.test.js} +10 -9
- package/dist/test/suites/main/auth.test.js +336 -0
- package/dist/test/suites/main/auto-updater.test.js +134 -134
- package/dist/test/suites/main/boot-sequence.test.js +37 -49
- package/dist/test/suites/main/context-menu.test.js +51 -50
- package/dist/test/suites/main/context.test.js +25 -25
- package/dist/test/suites/main/deep-link.test.js +74 -74
- package/dist/test/suites/main/fontawesome.test.js +27 -27
- package/dist/test/suites/main/ipc.test.js +35 -35
- package/dist/test/suites/main/menu.test.js +101 -100
- package/dist/test/suites/main/protocol.test.js +19 -19
- package/dist/test/suites/main/remote-config.test.js +63 -63
- package/dist/test/suites/main/remote-scripts.test.js +103 -103
- package/dist/test/suites/main/request.test.js +71 -0
- package/dist/test/suites/main/restart-manager.test.js +33 -33
- package/dist/test/suites/main/startup-paths-and-ua.test.js +4 -4
- package/dist/test/suites/main/startup.test.js +26 -26
- package/dist/test/suites/main/stealth-window.test.js +1 -1
- package/dist/test/suites/main/storage.test.js +25 -25
- package/dist/test/suites/main/theme.test.js +34 -34
- package/dist/test/suites/main/tray.test.js +79 -79
- package/dist/test/suites/main/url-helpers.test.js +133 -133
- package/dist/test/suites/main/usage.test.js +25 -25
- package/dist/test/suites/main/window-bounds.test.js +27 -27
- package/dist/test/suites/main/window-manager.test.js +44 -44
- package/dist/test/suites/renderer/analytics-bridge.test.js +5 -5
- package/dist/test/suites/renderer/cross-context-helpers.test.js +37 -31
- package/dist/test/suites/renderer/round-trip.test.js +3 -3
- package/dist/test/suites/renderer/tooltips.test.js +15 -15
- package/dist/test/suites/renderer/{window-em-surface.test.js → window-desktop-surface.test.js} +28 -8
- package/dist/test/utils/extended-mode-warning.js +1 -1
- package/dist/utils/boot-harness.js +56 -0
- package/dist/utils/build-pipeline.js +4 -4
- package/dist/utils/mode-helpers.js +2 -15
- package/dist/utils/runner-env.js +13 -28
- package/dist/utils/ship-keys.js +3 -3
- package/dist/utils/signing-status.js +51 -0
- package/dist/utils/test-events.js +7 -0
- package/dist/utils/test-stealth.js +6 -6
- package/dist/utils/url-helpers.js +52 -42
- package/dist/utils/user-agent.js +44 -0
- package/dist/vendor/account/engine.js +3 -3
- package/dist/vendor/account/index.js +14 -45
- package/dist/vendor/account/resolve-account.js +44 -0
- package/dist/vendor/account/schema.js +1 -1
- package/dist/vendor/account/user.js +99 -0
- package/dist/vendor/config/client-config.js +1 -1
- package/dist/vendor/config/company.js +46 -14
- package/dist/vendor/config/defaults.js +30 -7
- package/dist/vendor/config/edit.js +25 -3
- package/dist/vendor/config/env-delivery.js +1 -1
- package/dist/vendor/config/env-schema.js +3 -6
- package/dist/vendor/config/env.js +34 -22
- package/dist/vendor/config/environment.js +11 -30
- package/dist/vendor/config/index.js +21 -28
- package/dist/vendor/config/load.js +16 -9
- package/dist/vendor/config/platforms.js +1 -1
- package/dist/vendor/config/repo.js +10 -27
- package/dist/vendor/config/schema-client.js +64 -0
- package/dist/vendor/config/schema-cloud.js +38 -0
- package/dist/vendor/config/schema-manager.js +118 -0
- package/dist/vendor/config/schema-overrides.js +68 -0
- package/dist/vendor/config/schema.js +104 -160
- package/dist/vendor/config/site-global.js +2 -3
- package/dist/vendor/config/validate.js +97 -78
- package/dist/vendor/config/winback.js +1 -1
- package/dist/vendor/devkit/actions-secrets.js +1 -1
- package/dist/vendor/devkit/agents-md.js +233 -0
- package/dist/vendor/devkit/attach-log-file.js +16 -2
- package/dist/vendor/devkit/build-json.js +1 -1
- package/dist/vendor/devkit/ci-workflows.js +30 -30
- package/dist/vendor/devkit/cli-router.js +16 -11
- package/dist/vendor/devkit/defaults-engine.js +15 -51
- package/dist/vendor/devkit/deploy-snapshot.js +44 -9
- package/dist/vendor/devkit/env-lines.js +183 -0
- package/dist/vendor/devkit/local.js +64 -10
- package/dist/vendor/devkit/lockfile.js +32 -13
- package/dist/vendor/devkit/logger.js +7 -2
- package/dist/vendor/devkit/merge-line-files.js +219 -177
- package/dist/vendor/devkit/omega-bin.js +208 -111
- package/dist/vendor/devkit/preludes/docs-sync.js +52 -0
- package/dist/vendor/devkit/preludes/index.js +1 -0
- package/dist/vendor/devkit/target-picker.js +45 -0
- package/dist/vendor/devkit/test/dashed-files.js +37 -0
- package/dist/vendor/devkit/test/run-verb-under-tee.js +71 -0
- package/dist/vendor/devkit/test/runner-core.js +6 -6
- package/dist/vendor/devkit/update.js +15 -15
- package/dist/vendor/devkit/verb-scripts.js +40 -0
- package/dist/vendor/devkit/verbs.js +170 -0
- package/dist/vendor/monitoring/env.js +2 -2
- package/dist/vendor/monitoring/index.js +1 -1
- package/dist/vendor/monitoring/main.js +1 -1
- package/dist/vendor/monitoring/preload.js +1 -1
- package/dist/vendor/monitoring/renderer.js +1 -1
- package/package.json +19 -26
- package/dist/commands/install.js +0 -37
- package/dist/defaults/AGENTS.md +0 -110
- package/dist/defaults/CLAUDE.md +0 -1
- package/dist/lib/client-bridge.js +0 -374
- package/dist/lib/logger.js +0 -4
- package/dist/test/suites/build/manager.test.js +0 -213
- package/dist/test/suites/main/client-bridge.test.js +0 -262
- package/dist/vendor/config/env-retired.js +0 -137
- package/dist/vendor/config/retired-keys.js +0 -635
- package/docs/analytics.md +0 -140
- package/docs/app-state.md +0 -92
- package/docs/audit.md +0 -69
- package/docs/auto-updater.md +0 -243
- package/docs/boot-sequence.md +0 -39
- package/docs/build-system.md +0 -169
- package/docs/cdp-debugging.md +0 -169
- package/docs/client-bridge.md +0 -269
- package/docs/common-mistakes.md +0 -21
- package/docs/config-schema.md +0 -120
- package/docs/context-menu.md +0 -112
- package/docs/context.md +0 -81
- package/docs/css.md +0 -90
- package/docs/deep-link.md +0 -186
- package/docs/environment-detection.md +0 -112
- package/docs/fontawesome.md +0 -107
- package/docs/hooks.md +0 -89
- package/docs/icons.md +0 -79
- package/docs/index.md +0 -317
- package/docs/installer-options.md +0 -165
- package/docs/ipc.md +0 -61
- package/docs/lib-modules.md +0 -53
- package/docs/logging.md +0 -229
- package/docs/menu.md +0 -160
- package/docs/releasing.md +0 -239
- package/docs/remote-config.md +0 -118
- package/docs/remote-scripts.md +0 -144
- package/docs/restart-manager.md +0 -144
- package/docs/runner.md +0 -290
- package/docs/sentry.md +0 -97
- package/docs/shared/agent-docs.md +0 -89
- package/docs/shared/analytics.md +0 -612
- package/docs/shared/brands.md +0 -57
- package/docs/shared/breaking-changes.md +0 -851
- package/docs/shared/config.md +0 -1952
- package/docs/shared/deploys.md +0 -341
- package/docs/shared/icons.md +0 -219
- package/docs/shared/local-dev.md +0 -167
- package/docs/shared/logging.md +0 -205
- package/docs/shared/monitoring.md +0 -167
- package/docs/shared/publishing.md +0 -187
- package/docs/shared/rulings.md +0 -34
- package/docs/shared/testing.md +0 -147
- package/docs/shared/theming.md +0 -629
- package/docs/shared/translation.md +0 -333
- package/docs/shared/updates.md +0 -61
- package/docs/signing.md +0 -293
- package/docs/startup.md +0 -142
- package/docs/storage.md +0 -59
- package/docs/templating.md +0 -101
- package/docs/test-boot-layer.md +0 -157
- package/docs/test-framework.md +0 -362
- package/docs/themes.md +0 -149
- package/docs/tooltips.md +0 -99
- package/docs/tray.md +0 -164
- package/docs/usage.md +0 -58
- package/docs/verts.md +0 -62
- package/docs/windows.md +0 -149
|
@@ -15,11 +15,11 @@ module.exports = defineCases({
|
|
|
15
15
|
description: 'ipc (main)',
|
|
16
16
|
cleanup: (ctx) => {
|
|
17
17
|
// Always tear down the test channels so suites don't bleed into each other.
|
|
18
|
-
if (ctx.
|
|
19
|
-
ctx.
|
|
18
|
+
if (ctx.omega.ipc.hasHandler(TEST_CHANNEL)) {
|
|
19
|
+
ctx.omega.ipc.unhandle(TEST_CHANNEL);
|
|
20
20
|
}
|
|
21
21
|
// Best-effort: drain test listeners.
|
|
22
|
-
while (ctx.
|
|
22
|
+
while (ctx.omega.ipc.listenerCount(TEST_LISTEN) > 0) {
|
|
23
23
|
// off() needs the original fn; nothing left to remove if our local refs are gone.
|
|
24
24
|
// The listenerCount === 0 guard in off() will leave the registry clean once tests unsubscribe themselves.
|
|
25
25
|
break;
|
|
@@ -29,26 +29,26 @@ module.exports = defineCases({
|
|
|
29
29
|
{
|
|
30
30
|
name: 'initialized after boot',
|
|
31
31
|
run: (ctx) => {
|
|
32
|
-
ctx.expect(ctx.
|
|
32
|
+
ctx.expect(ctx.omega.ipc._initialized).toBe(true);
|
|
33
33
|
},
|
|
34
34
|
},
|
|
35
35
|
{
|
|
36
36
|
name: 'storage handlers are registered on the ipc bus',
|
|
37
37
|
run: (ctx) => {
|
|
38
|
-
ctx.expect(ctx.
|
|
39
|
-
ctx.expect(ctx.
|
|
40
|
-
ctx.expect(ctx.
|
|
41
|
-
ctx.expect(ctx.
|
|
42
|
-
ctx.expect(ctx.
|
|
38
|
+
ctx.expect(ctx.omega.ipc.hasHandler('desktop:storage:get')).toBe(true);
|
|
39
|
+
ctx.expect(ctx.omega.ipc.hasHandler('desktop:storage:set')).toBe(true);
|
|
40
|
+
ctx.expect(ctx.omega.ipc.hasHandler('desktop:storage:delete')).toBe(true);
|
|
41
|
+
ctx.expect(ctx.omega.ipc.hasHandler('desktop:storage:has')).toBe(true);
|
|
42
|
+
ctx.expect(ctx.omega.ipc.hasHandler('desktop:storage:clear')).toBe(true);
|
|
43
43
|
},
|
|
44
44
|
},
|
|
45
45
|
{
|
|
46
46
|
name: 'handle + invoke round-trip',
|
|
47
47
|
run: async (ctx) => {
|
|
48
|
-
ctx.
|
|
48
|
+
ctx.omega.ipc.handle(TEST_CHANNEL, (payload) => {
|
|
49
49
|
return { echoed: payload.value };
|
|
50
50
|
});
|
|
51
|
-
const result = await ctx.
|
|
51
|
+
const result = await ctx.omega.ipc.invoke(TEST_CHANNEL, { value: 42 });
|
|
52
52
|
ctx.expect(result).toEqual({ echoed: 42 });
|
|
53
53
|
},
|
|
54
54
|
},
|
|
@@ -57,15 +57,15 @@ module.exports = defineCases({
|
|
|
57
57
|
run: (ctx) => {
|
|
58
58
|
// The previous test left TEST_CHANNEL registered.
|
|
59
59
|
ctx.expect(() => {
|
|
60
|
-
ctx.
|
|
60
|
+
ctx.omega.ipc.handle(TEST_CHANNEL, () => 'dup');
|
|
61
61
|
}).toThrow(/already has a handler/);
|
|
62
62
|
},
|
|
63
63
|
},
|
|
64
64
|
{
|
|
65
65
|
name: 'unhandle removes the handler',
|
|
66
66
|
run: (ctx) => {
|
|
67
|
-
ctx.
|
|
68
|
-
ctx.expect(ctx.
|
|
67
|
+
ctx.omega.ipc.unhandle(TEST_CHANNEL);
|
|
68
|
+
ctx.expect(ctx.omega.ipc.hasHandler(TEST_CHANNEL)).toBe(false);
|
|
69
69
|
},
|
|
70
70
|
},
|
|
71
71
|
{
|
|
@@ -73,7 +73,7 @@ module.exports = defineCases({
|
|
|
73
73
|
run: async (ctx) => {
|
|
74
74
|
let err;
|
|
75
75
|
try {
|
|
76
|
-
await ctx.
|
|
76
|
+
await ctx.omega.ipc.invoke(TEST_CHANNEL, {});
|
|
77
77
|
} catch (e) {
|
|
78
78
|
err = e;
|
|
79
79
|
}
|
|
@@ -84,28 +84,28 @@ module.exports = defineCases({
|
|
|
84
84
|
{
|
|
85
85
|
name: 'handler errors propagate through invoke',
|
|
86
86
|
run: async (ctx) => {
|
|
87
|
-
ctx.
|
|
87
|
+
ctx.omega.ipc.handle(TEST_CHANNEL, () => {
|
|
88
88
|
throw new Error('boom');
|
|
89
89
|
});
|
|
90
90
|
let err;
|
|
91
91
|
try {
|
|
92
|
-
await ctx.
|
|
92
|
+
await ctx.omega.ipc.invoke(TEST_CHANNEL, {});
|
|
93
93
|
} catch (e) {
|
|
94
94
|
err = e;
|
|
95
95
|
}
|
|
96
96
|
ctx.expect(err).toBeDefined();
|
|
97
97
|
ctx.expect(err.message).toBe('boom');
|
|
98
|
-
ctx.
|
|
98
|
+
ctx.omega.ipc.unhandle(TEST_CHANNEL);
|
|
99
99
|
},
|
|
100
100
|
},
|
|
101
101
|
{
|
|
102
102
|
name: 'on registers a listener and returns an unsubscribe fn',
|
|
103
103
|
run: (ctx) => {
|
|
104
104
|
const fn = () => {};
|
|
105
|
-
const off = ctx.
|
|
106
|
-
ctx.expect(ctx.
|
|
105
|
+
const off = ctx.omega.ipc.on(TEST_LISTEN, fn);
|
|
106
|
+
ctx.expect(ctx.omega.ipc.listenerCount(TEST_LISTEN)).toBe(1);
|
|
107
107
|
off();
|
|
108
|
-
ctx.expect(ctx.
|
|
108
|
+
ctx.expect(ctx.omega.ipc.listenerCount(TEST_LISTEN)).toBe(0);
|
|
109
109
|
},
|
|
110
110
|
},
|
|
111
111
|
{
|
|
@@ -113,13 +113,13 @@ module.exports = defineCases({
|
|
|
113
113
|
run: (ctx) => {
|
|
114
114
|
const a = () => {};
|
|
115
115
|
const b = () => {};
|
|
116
|
-
const offA = ctx.
|
|
117
|
-
const offB = ctx.
|
|
118
|
-
ctx.expect(ctx.
|
|
116
|
+
const offA = ctx.omega.ipc.on(TEST_LISTEN, a);
|
|
117
|
+
const offB = ctx.omega.ipc.on(TEST_LISTEN, b);
|
|
118
|
+
ctx.expect(ctx.omega.ipc.listenerCount(TEST_LISTEN)).toBe(2);
|
|
119
119
|
offA();
|
|
120
|
-
ctx.expect(ctx.
|
|
120
|
+
ctx.expect(ctx.omega.ipc.listenerCount(TEST_LISTEN)).toBe(1);
|
|
121
121
|
offB();
|
|
122
|
-
ctx.expect(ctx.
|
|
122
|
+
ctx.expect(ctx.omega.ipc.listenerCount(TEST_LISTEN)).toBe(0);
|
|
123
123
|
},
|
|
124
124
|
},
|
|
125
125
|
{
|
|
@@ -127,15 +127,15 @@ module.exports = defineCases({
|
|
|
127
127
|
run: (ctx) => {
|
|
128
128
|
// Test harness runs with skipWindowCreation: true — no BrowserWindows exist.
|
|
129
129
|
// This must not throw.
|
|
130
|
-
ctx.
|
|
130
|
+
ctx.omega.ipc.broadcast('desktop:test:broadcast', { hello: 'world' });
|
|
131
131
|
ctx.expect(true).toBe(true);
|
|
132
132
|
},
|
|
133
133
|
},
|
|
134
134
|
{
|
|
135
135
|
name: 'send to a destroyed/null webContents is a safe no-op',
|
|
136
136
|
run: (ctx) => {
|
|
137
|
-
ctx.
|
|
138
|
-
ctx.
|
|
137
|
+
ctx.omega.ipc.send(null, 'desktop:test:send', {});
|
|
138
|
+
ctx.omega.ipc.send({ isDestroyed: () => true }, 'desktop:test:send', {});
|
|
139
139
|
ctx.expect(true).toBe(true);
|
|
140
140
|
},
|
|
141
141
|
},
|
|
@@ -143,22 +143,22 @@ module.exports = defineCases({
|
|
|
143
143
|
name: 'storage.set triggers ipc broadcast (no throw with zero renderers)',
|
|
144
144
|
run: (ctx) => {
|
|
145
145
|
// storage._broadcast routes through ipc.broadcast — confirm it runs cleanly here.
|
|
146
|
-
ctx.
|
|
147
|
-
ctx.expect(ctx.
|
|
148
|
-
ctx.
|
|
146
|
+
ctx.omega.storage.set('ipc-broadcast-probe', 1);
|
|
147
|
+
ctx.expect(ctx.omega.storage.get('ipc-broadcast-probe')).toBe(1);
|
|
148
|
+
ctx.omega.storage.delete('ipc-broadcast-probe');
|
|
149
149
|
},
|
|
150
150
|
},
|
|
151
151
|
{
|
|
152
152
|
name: 'handle rejects non-string channel',
|
|
153
153
|
run: (ctx) => {
|
|
154
|
-
ctx.expect(() => ctx.
|
|
155
|
-
ctx.expect(() => ctx.
|
|
154
|
+
ctx.expect(() => ctx.omega.ipc.handle('', () => {})).toThrow(/non-empty string/);
|
|
155
|
+
ctx.expect(() => ctx.omega.ipc.handle(null, () => {})).toThrow(/non-empty string/);
|
|
156
156
|
},
|
|
157
157
|
},
|
|
158
158
|
{
|
|
159
159
|
name: 'handle rejects non-function handler',
|
|
160
160
|
run: (ctx) => {
|
|
161
|
-
ctx.expect(() => ctx.
|
|
161
|
+
ctx.expect(() => ctx.omega.ipc.handle('desktop:test:bad', null)).toThrow(/handler must be a function/);
|
|
162
162
|
},
|
|
163
163
|
},
|
|
164
164
|
],
|
|
@@ -10,19 +10,19 @@ module.exports = defineCases({
|
|
|
10
10
|
layer: 'main',
|
|
11
11
|
description: 'menu (main)',
|
|
12
12
|
cleanup: (ctx) => {
|
|
13
|
-
ctx.
|
|
13
|
+
ctx.omega.menu.destroy();
|
|
14
14
|
},
|
|
15
15
|
tests: [
|
|
16
16
|
{
|
|
17
17
|
name: 'initialize ran (enabled by default)',
|
|
18
18
|
run: (ctx) => {
|
|
19
|
-
ctx.expect(ctx.
|
|
19
|
+
ctx.expect(ctx.omega.menu._initialized).toBe(true);
|
|
20
20
|
},
|
|
21
21
|
},
|
|
22
22
|
{
|
|
23
23
|
name: 'no consumer definition file → default template loaded',
|
|
24
24
|
run: (ctx) => {
|
|
25
|
-
const items = ctx.
|
|
25
|
+
const items = ctx.omega.menu.getItems();
|
|
26
26
|
ctx.expect(Array.isArray(items)).toBe(true);
|
|
27
27
|
ctx.expect(items.length).toBeGreaterThan(0);
|
|
28
28
|
|
|
@@ -36,8 +36,8 @@ module.exports = defineCases({
|
|
|
36
36
|
{
|
|
37
37
|
name: 'default template renders and Menu.setApplicationMenu was called',
|
|
38
38
|
run: (ctx) => {
|
|
39
|
-
ctx.expect(ctx.
|
|
40
|
-
ctx.expect(ctx.
|
|
39
|
+
ctx.expect(ctx.omega.menu.isRendered()).toBe(true);
|
|
40
|
+
ctx.expect(ctx.omega.menu.getMenu()).toBeTruthy();
|
|
41
41
|
},
|
|
42
42
|
},
|
|
43
43
|
{
|
|
@@ -47,15 +47,15 @@ module.exports = defineCases({
|
|
|
47
47
|
ctx.skip('macOS-only behavior');
|
|
48
48
|
}
|
|
49
49
|
// Menu falls back to brand.name when no productName is configured (lib/menu.js).
|
|
50
|
-
const productName = ctx.
|
|
51
|
-
const items = ctx.
|
|
50
|
+
const productName = ctx.omega.config.app?.productName || ctx.omega.config.brand.name;
|
|
51
|
+
const items = ctx.omega.menu.getItems();
|
|
52
52
|
ctx.expect(items[0].label).toBe(productName);
|
|
53
53
|
},
|
|
54
54
|
},
|
|
55
55
|
{
|
|
56
56
|
name: 'define() runs the builder fn and replaces items',
|
|
57
57
|
run: (ctx) => {
|
|
58
|
-
ctx.
|
|
58
|
+
ctx.omega.menu.define(({ menu }) => {
|
|
59
59
|
menu.menu('Test', [
|
|
60
60
|
{ label: 'Hello', click: () => {} },
|
|
61
61
|
{ type: 'separator' },
|
|
@@ -63,7 +63,7 @@ module.exports = defineCases({
|
|
|
63
63
|
]);
|
|
64
64
|
});
|
|
65
65
|
|
|
66
|
-
const items = ctx.
|
|
66
|
+
const items = ctx.omega.menu.getItems();
|
|
67
67
|
ctx.expect(items.length).toBe(1);
|
|
68
68
|
ctx.expect(items[0].label).toBe('Test');
|
|
69
69
|
ctx.expect(Array.isArray(items[0].submenu)).toBe(true);
|
|
@@ -73,28 +73,28 @@ module.exports = defineCases({
|
|
|
73
73
|
{
|
|
74
74
|
name: 'define() throws on non-function input',
|
|
75
75
|
run: (ctx) => {
|
|
76
|
-
ctx.expect(() => ctx.
|
|
76
|
+
ctx.expect(() => ctx.omega.menu.define(null)).toThrow(/must be a function/);
|
|
77
77
|
},
|
|
78
78
|
},
|
|
79
79
|
{
|
|
80
80
|
name: 'menu.menu(label, items) appends a top-level entry',
|
|
81
81
|
run: (ctx) => {
|
|
82
|
-
ctx.
|
|
82
|
+
ctx.omega.menu.define(({ menu }) => {
|
|
83
83
|
menu.menu('First', [{ label: 'a' }]);
|
|
84
84
|
menu.menu('Second', [{ label: 'b' }]);
|
|
85
85
|
});
|
|
86
|
-
const labels = ctx.
|
|
86
|
+
const labels = ctx.omega.menu.getItems().map((i) => i.label);
|
|
87
87
|
ctx.expect(labels).toEqual(['First', 'Second']);
|
|
88
88
|
},
|
|
89
89
|
},
|
|
90
90
|
{
|
|
91
91
|
name: 'useDefaults() replaces items with the platform default template',
|
|
92
92
|
run: (ctx) => {
|
|
93
|
-
ctx.
|
|
93
|
+
ctx.omega.menu.define(({ menu }) => {
|
|
94
94
|
menu.menu('Custom', [{ label: 'x' }]);
|
|
95
95
|
menu.useDefaults();
|
|
96
96
|
});
|
|
97
|
-
const labels = ctx.
|
|
97
|
+
const labels = ctx.omega.menu.getItems().map((i) => i.label);
|
|
98
98
|
ctx.expect(labels).toContain('Edit');
|
|
99
99
|
ctx.expect(labels).not.toContain('Custom');
|
|
100
100
|
},
|
|
@@ -102,20 +102,20 @@ module.exports = defineCases({
|
|
|
102
102
|
{
|
|
103
103
|
name: 'clear() empties the items list',
|
|
104
104
|
run: (ctx) => {
|
|
105
|
-
ctx.
|
|
105
|
+
ctx.omega.menu.define(({ menu }) => {
|
|
106
106
|
menu.menu('A', [{ label: 'a' }]);
|
|
107
107
|
menu.clear();
|
|
108
108
|
});
|
|
109
|
-
ctx.expect(ctx.
|
|
109
|
+
ctx.expect(ctx.omega.menu.getItems()).toEqual([]);
|
|
110
110
|
},
|
|
111
111
|
},
|
|
112
112
|
{
|
|
113
113
|
name: 'append() adds a raw descriptor at top level',
|
|
114
114
|
run: (ctx) => {
|
|
115
|
-
ctx.
|
|
115
|
+
ctx.omega.menu.define(({ menu }) => {
|
|
116
116
|
menu.append({ label: 'Raw', submenu: [{ label: 'inside' }] });
|
|
117
117
|
});
|
|
118
|
-
const items = ctx.
|
|
118
|
+
const items = ctx.omega.menu.getItems();
|
|
119
119
|
ctx.expect(items.length).toBe(1);
|
|
120
120
|
ctx.expect(items[0].label).toBe('Raw');
|
|
121
121
|
},
|
|
@@ -124,16 +124,16 @@ module.exports = defineCases({
|
|
|
124
124
|
name: 'dynamic label functions are evaluated at resolve time',
|
|
125
125
|
run: (ctx) => {
|
|
126
126
|
let count = 0;
|
|
127
|
-
ctx.
|
|
127
|
+
ctx.omega.menu.define(({ menu }) => {
|
|
128
128
|
menu.menu('Counter', [{ label: () => `Count: ${count}` }]);
|
|
129
129
|
});
|
|
130
130
|
|
|
131
|
-
const item = ctx.
|
|
132
|
-
const resolved1 = ctx.
|
|
131
|
+
const item = ctx.omega.menu.getItems()[0].submenu[0];
|
|
132
|
+
const resolved1 = ctx.omega.menu._resolveItem(item);
|
|
133
133
|
ctx.expect(resolved1.label).toBe('Count: 0');
|
|
134
134
|
|
|
135
135
|
count = 7;
|
|
136
|
-
const resolved2 = ctx.
|
|
136
|
+
const resolved2 = ctx.omega.menu._resolveItem(item);
|
|
137
137
|
ctx.expect(resolved2.label).toBe('Count: 7');
|
|
138
138
|
},
|
|
139
139
|
},
|
|
@@ -141,13 +141,13 @@ module.exports = defineCases({
|
|
|
141
141
|
name: 'click handlers are wrapped to catch errors',
|
|
142
142
|
run: (ctx) => {
|
|
143
143
|
let called = false;
|
|
144
|
-
ctx.
|
|
144
|
+
ctx.omega.menu.define(({ menu }) => {
|
|
145
145
|
menu.menu('M', [
|
|
146
146
|
{ label: 'Boom', click: () => { called = true; throw new Error('boom'); } },
|
|
147
147
|
]);
|
|
148
148
|
});
|
|
149
|
-
const inner = ctx.
|
|
150
|
-
const resolved = ctx.
|
|
149
|
+
const inner = ctx.omega.menu.getItems()[0].submenu[0];
|
|
150
|
+
const resolved = ctx.omega.menu._resolveItem(inner);
|
|
151
151
|
resolved.click(null, null, null);
|
|
152
152
|
ctx.expect(called).toBe(true);
|
|
153
153
|
},
|
|
@@ -155,7 +155,7 @@ module.exports = defineCases({
|
|
|
155
155
|
{
|
|
156
156
|
name: 'submenu items are recursively resolved',
|
|
157
157
|
run: (ctx) => {
|
|
158
|
-
ctx.
|
|
158
|
+
ctx.omega.menu.define(({ menu }) => {
|
|
159
159
|
menu.menu('Top', [
|
|
160
160
|
{
|
|
161
161
|
label: 'Parent',
|
|
@@ -166,8 +166,8 @@ module.exports = defineCases({
|
|
|
166
166
|
},
|
|
167
167
|
]);
|
|
168
168
|
});
|
|
169
|
-
const top = ctx.
|
|
170
|
-
const resolved = ctx.
|
|
169
|
+
const top = ctx.omega.menu.getItems()[0];
|
|
170
|
+
const resolved = ctx.omega.menu._resolveItem(top);
|
|
171
171
|
ctx.expect(resolved.submenu[0].label).toBe('Parent');
|
|
172
172
|
ctx.expect(resolved.submenu[0].submenu[0].label).toBe('Dyn child');
|
|
173
173
|
ctx.expect(resolved.submenu[0].submenu[1].type).toBe('separator');
|
|
@@ -176,10 +176,10 @@ module.exports = defineCases({
|
|
|
176
176
|
{
|
|
177
177
|
name: 'default template includes platform-appropriate check-for-updates item',
|
|
178
178
|
run: (ctx) => {
|
|
179
|
-
ctx.
|
|
179
|
+
ctx.omega.menu.define(({ menu: m }) => m.useDefaults());
|
|
180
180
|
// Mac → main/check-for-updates; win/linux → help/check-for-updates.
|
|
181
181
|
const id = process.platform === 'darwin' ? 'main/check-for-updates' : 'help/check-for-updates';
|
|
182
|
-
const item = ctx.
|
|
182
|
+
const item = ctx.omega.menu.find(id);
|
|
183
183
|
ctx.expect(item).toBeTruthy();
|
|
184
184
|
ctx.expect(typeof item.label).toBe('string');
|
|
185
185
|
ctx.expect(typeof item.click).toBe('function');
|
|
@@ -188,24 +188,24 @@ module.exports = defineCases({
|
|
|
188
188
|
{
|
|
189
189
|
name: 'find returns null for unknown id',
|
|
190
190
|
run: (ctx) => {
|
|
191
|
-
ctx.expect(ctx.
|
|
191
|
+
ctx.expect(ctx.omega.menu.find('does-not-exist')).toBe(null);
|
|
192
192
|
},
|
|
193
193
|
},
|
|
194
194
|
{
|
|
195
195
|
name: 'update patches label and re-renders',
|
|
196
196
|
run: (ctx) => {
|
|
197
|
-
ctx.
|
|
197
|
+
ctx.omega.menu.define(({ menu: m }) => m.useDefaults());
|
|
198
198
|
const id = process.platform === 'darwin' ? 'main/check-for-updates' : 'help/check-for-updates';
|
|
199
|
-
const ok = ctx.
|
|
199
|
+
const ok = ctx.omega.menu.update(id, { label: 'PROBE LABEL' });
|
|
200
200
|
ctx.expect(ok).toBe(true);
|
|
201
|
-
const item = ctx.
|
|
201
|
+
const item = ctx.omega.menu.find(id);
|
|
202
202
|
ctx.expect(item.label).toBe('PROBE LABEL');
|
|
203
203
|
},
|
|
204
204
|
},
|
|
205
205
|
{
|
|
206
206
|
name: 'update returns false for unknown id',
|
|
207
207
|
run: (ctx) => {
|
|
208
|
-
const ok = ctx.
|
|
208
|
+
const ok = ctx.omega.menu.update('nope', { label: 'nope' });
|
|
209
209
|
ctx.expect(ok).toBe(false);
|
|
210
210
|
},
|
|
211
211
|
},
|
|
@@ -213,41 +213,41 @@ module.exports = defineCases({
|
|
|
213
213
|
name: 'remove deletes item from tree',
|
|
214
214
|
run: (ctx) => {
|
|
215
215
|
// Recreate the default template so we have the item to remove (previous test may have mutated).
|
|
216
|
-
ctx.
|
|
216
|
+
ctx.omega.menu.define(({ menu: m }) => m.useDefaults());
|
|
217
217
|
const id = process.platform === 'darwin' ? 'main/check-for-updates' : 'help/check-for-updates';
|
|
218
|
-
ctx.expect(ctx.
|
|
218
|
+
ctx.expect(ctx.omega.menu.find(id)).toBeTruthy();
|
|
219
219
|
|
|
220
|
-
const removed = ctx.
|
|
220
|
+
const removed = ctx.omega.menu.remove(id);
|
|
221
221
|
ctx.expect(removed).toBe(true);
|
|
222
|
-
ctx.expect(ctx.
|
|
222
|
+
ctx.expect(ctx.omega.menu.find(id)).toBe(null);
|
|
223
223
|
|
|
224
224
|
// Restore for subsequent tests.
|
|
225
|
-
ctx.
|
|
225
|
+
ctx.omega.menu.define(({ menu: m }) => m.useDefaults());
|
|
226
226
|
},
|
|
227
227
|
},
|
|
228
228
|
{
|
|
229
229
|
name: 'insertAfter splices in a new sibling by id-path',
|
|
230
230
|
run: (ctx) => {
|
|
231
|
-
ctx.
|
|
231
|
+
ctx.omega.menu.define(({ menu: m }) => m.useDefaults());
|
|
232
232
|
const anchor = process.platform === 'darwin' ? 'main/check-for-updates' : 'help/check-for-updates';
|
|
233
|
-
const ok = ctx.
|
|
233
|
+
const ok = ctx.omega.menu.insertAfter(anchor, { id: 'main/preferences', label: 'PREF PROBE' });
|
|
234
234
|
ctx.expect(ok).toBe(true);
|
|
235
|
-
ctx.expect(ctx.
|
|
235
|
+
ctx.expect(ctx.omega.menu.find('main/preferences')).toBeTruthy();
|
|
236
236
|
},
|
|
237
237
|
},
|
|
238
238
|
{
|
|
239
239
|
name: 'auto-updater status updates the menu item label',
|
|
240
240
|
run: async (ctx) => {
|
|
241
|
-
ctx.
|
|
241
|
+
ctx.omega.menu.define(({ menu: m }) => m.useDefaults());
|
|
242
242
|
|
|
243
243
|
// Force a known state and trigger menu update.
|
|
244
|
-
ctx.
|
|
244
|
+
ctx.omega.autoUpdater._state = {
|
|
245
245
|
code: 'downloaded', version: '5.0.0', percent: 100, error: null, downloadedAt: Date.now(), lastCheckedAt: null,
|
|
246
246
|
};
|
|
247
|
-
ctx.
|
|
247
|
+
ctx.omega.autoUpdater._updateMenuItem();
|
|
248
248
|
|
|
249
249
|
const id = process.platform === 'darwin' ? 'main/check-for-updates' : 'help/check-for-updates';
|
|
250
|
-
const item = ctx.
|
|
250
|
+
const item = ctx.omega.menu.find(id);
|
|
251
251
|
ctx.expect(item.label).toContain('Restart to Update');
|
|
252
252
|
ctx.expect(item.label).toContain('5.0.0');
|
|
253
253
|
ctx.expect(item.enabled).toBe(true);
|
|
@@ -256,28 +256,29 @@ module.exports = defineCases({
|
|
|
256
256
|
{
|
|
257
257
|
name: 'auto-updater downloading status disables item',
|
|
258
258
|
run: (ctx) => {
|
|
259
|
-
ctx.
|
|
259
|
+
ctx.omega.menu.define(({ menu: m }) => m.useDefaults());
|
|
260
260
|
|
|
261
|
-
ctx.
|
|
261
|
+
ctx.omega.autoUpdater._state = {
|
|
262
262
|
code: 'downloading', version: '5.0.0', percent: 42, error: null, downloadedAt: null, lastCheckedAt: null,
|
|
263
263
|
};
|
|
264
|
-
ctx.
|
|
264
|
+
ctx.omega.autoUpdater._updateMenuItem();
|
|
265
265
|
|
|
266
266
|
const id = process.platform === 'darwin' ? 'main/check-for-updates' : 'help/check-for-updates';
|
|
267
|
-
const item = ctx.
|
|
267
|
+
const item = ctx.omega.menu.find(id);
|
|
268
268
|
ctx.expect(item.label).toContain('42%');
|
|
269
269
|
ctx.expect(item.enabled).toBe(false);
|
|
270
270
|
},
|
|
271
271
|
},
|
|
272
272
|
{
|
|
273
|
-
name: 'consumer function receives
|
|
273
|
+
name: 'consumer function receives omega + menu builder + defaults (no manager key)',
|
|
274
274
|
run: (ctx) => {
|
|
275
275
|
let received;
|
|
276
|
-
ctx.
|
|
276
|
+
ctx.omega.menu.define((arg) => {
|
|
277
277
|
received = arg;
|
|
278
278
|
arg.menu.menu('probe', []);
|
|
279
279
|
});
|
|
280
|
-
ctx.expect(received.
|
|
280
|
+
ctx.expect(received.omega).toBe(ctx.omega);
|
|
281
|
+
ctx.expect(received.manager).toBeUndefined();
|
|
281
282
|
ctx.expect(typeof received.menu.menu).toBe('function');
|
|
282
283
|
ctx.expect(typeof received.menu.useDefaults).toBe('function');
|
|
283
284
|
ctx.expect(typeof received.menu.clear).toBe('function');
|
|
@@ -292,39 +293,39 @@ module.exports = defineCases({
|
|
|
292
293
|
{
|
|
293
294
|
name: 'menu.has reports presence by id-path',
|
|
294
295
|
run: (ctx) => {
|
|
295
|
-
ctx.
|
|
296
|
-
ctx.expect(ctx.
|
|
297
|
-
ctx.expect(ctx.
|
|
296
|
+
ctx.omega.menu.define(({ menu: m }) => m.useDefaults());
|
|
297
|
+
ctx.expect(ctx.omega.menu.has('edit/copy')).toBe(true);
|
|
298
|
+
ctx.expect(ctx.omega.menu.has('edit/does-not-exist')).toBe(false);
|
|
298
299
|
},
|
|
299
300
|
},
|
|
300
301
|
{
|
|
301
302
|
name: 'menu.hide / menu.show toggle visibility by id-path',
|
|
302
303
|
run: (ctx) => {
|
|
303
|
-
ctx.
|
|
304
|
-
ctx.
|
|
305
|
-
ctx.expect(ctx.
|
|
306
|
-
ctx.
|
|
307
|
-
ctx.expect(ctx.
|
|
304
|
+
ctx.omega.menu.define(({ menu: m }) => m.useDefaults());
|
|
305
|
+
ctx.omega.menu.hide('edit/copy');
|
|
306
|
+
ctx.expect(ctx.omega.menu.find('edit/copy').visible).toBe(false);
|
|
307
|
+
ctx.omega.menu.show('edit/copy');
|
|
308
|
+
ctx.expect(ctx.omega.menu.find('edit/copy').visible).toBe(true);
|
|
308
309
|
},
|
|
309
310
|
},
|
|
310
311
|
{
|
|
311
312
|
name: 'menu.enable toggles enabled by id-path',
|
|
312
313
|
run: (ctx) => {
|
|
313
|
-
ctx.
|
|
314
|
-
ctx.
|
|
315
|
-
ctx.expect(ctx.
|
|
316
|
-
ctx.
|
|
317
|
-
ctx.expect(ctx.
|
|
314
|
+
ctx.omega.menu.define(({ menu: m }) => m.useDefaults());
|
|
315
|
+
ctx.omega.menu.enable('edit/copy', false);
|
|
316
|
+
ctx.expect(ctx.omega.menu.find('edit/copy').enabled).toBe(false);
|
|
317
|
+
ctx.omega.menu.enable('edit/copy');
|
|
318
|
+
ctx.expect(ctx.omega.menu.find('edit/copy').enabled).toBe(true);
|
|
318
319
|
},
|
|
319
320
|
},
|
|
320
321
|
{
|
|
321
322
|
name: 'menu.insertBefore splices into a submenu by id-path',
|
|
322
323
|
run: (ctx) => {
|
|
323
|
-
ctx.
|
|
324
|
-
const ok = ctx.
|
|
324
|
+
ctx.omega.menu.define(({ menu: m }) => m.useDefaults());
|
|
325
|
+
const ok = ctx.omega.menu.insertBefore('edit/copy', { id: 'edit/probe', label: 'PROBE' });
|
|
325
326
|
ctx.expect(ok).toBe(true);
|
|
326
327
|
// Find the edit submenu and confirm probe is right before copy.
|
|
327
|
-
const edit = ctx.
|
|
328
|
+
const edit = ctx.omega.menu.find('edit');
|
|
328
329
|
const sub = edit.submenu;
|
|
329
330
|
const copyIdx = sub.findIndex((i) => i.id === 'edit/copy');
|
|
330
331
|
const probeIdx = sub.findIndex((i) => i.id === 'edit/probe');
|
|
@@ -334,45 +335,45 @@ module.exports = defineCases({
|
|
|
334
335
|
{
|
|
335
336
|
name: 'menu.appendTo pushes into a submenu (creating it if absent)',
|
|
336
337
|
run: (ctx) => {
|
|
337
|
-
ctx.
|
|
338
|
+
ctx.omega.menu.define(({ menu: m }) => {
|
|
338
339
|
m.menu('Tools', []);
|
|
339
340
|
});
|
|
340
|
-
const ok = ctx.
|
|
341
|
+
const ok = ctx.omega.menu.appendTo('Tools', { id: 'tools/x', label: 'X' });
|
|
341
342
|
// 'Tools' was added with label='Tools' but no id field — appendTo lookups id-path,
|
|
342
343
|
// so this should miss. Use a different anchor that has an id.
|
|
343
344
|
ctx.expect(ok).toBe(false);
|
|
344
345
|
|
|
345
|
-
ctx.
|
|
346
|
+
ctx.omega.menu.define(({ menu: m }) => {
|
|
346
347
|
m.append({ id: 'tools', label: 'Tools', submenu: [] });
|
|
347
348
|
});
|
|
348
|
-
const ok2 = ctx.
|
|
349
|
+
const ok2 = ctx.omega.menu.appendTo('tools', { id: 'tools/x', label: 'X' });
|
|
349
350
|
ctx.expect(ok2).toBe(true);
|
|
350
|
-
ctx.expect(ctx.
|
|
351
|
+
ctx.expect(ctx.omega.menu.find('tools').submenu[0].id).toBe('tools/x');
|
|
351
352
|
},
|
|
352
353
|
},
|
|
353
354
|
{
|
|
354
355
|
name: 'menu deep-path lookup walks segments (view/developer/toggle-devtools)',
|
|
355
356
|
run: (ctx) => {
|
|
356
357
|
// Force isDevelopment() so the dev menu renders.
|
|
357
|
-
const orig = ctx.
|
|
358
|
-
ctx.
|
|
358
|
+
const orig = ctx.omega.isDevelopment;
|
|
359
|
+
ctx.omega.isDevelopment = () => true;
|
|
359
360
|
try {
|
|
360
|
-
ctx.
|
|
361
|
-
ctx.expect(ctx.
|
|
362
|
-
ctx.expect(ctx.
|
|
361
|
+
ctx.omega.menu.define(({ menu: m }) => m.useDefaults());
|
|
362
|
+
ctx.expect(ctx.omega.menu.has('view/developer')).toBe(true);
|
|
363
|
+
ctx.expect(ctx.omega.menu.has('view/developer/toggle-devtools')).toBe(true);
|
|
363
364
|
} finally {
|
|
364
|
-
ctx.
|
|
365
|
+
ctx.omega.isDevelopment = orig;
|
|
365
366
|
}
|
|
366
367
|
},
|
|
367
368
|
},
|
|
368
369
|
{
|
|
369
370
|
name: 'view/developer carries the Simulate update submenu (dev only)',
|
|
370
371
|
run: (ctx) => {
|
|
371
|
-
const orig = ctx.
|
|
372
|
-
ctx.
|
|
372
|
+
const orig = ctx.omega.isDevelopment;
|
|
373
|
+
ctx.omega.isDevelopment = () => true;
|
|
373
374
|
try {
|
|
374
|
-
ctx.
|
|
375
|
-
const item = ctx.
|
|
375
|
+
ctx.omega.menu.define(({ menu: m }) => m.useDefaults());
|
|
376
|
+
const item = ctx.omega.menu.find('view/developer/simulate-update');
|
|
376
377
|
ctx.expect(item).toBeTruthy();
|
|
377
378
|
ctx.expect(item.label).toBe('Simulate update');
|
|
378
379
|
ctx.expect(item.submenu.map((i) => i.id)).toEqual([
|
|
@@ -381,37 +382,37 @@ module.exports = defineCases({
|
|
|
381
382
|
'view/developer/simulate-update/error',
|
|
382
383
|
]);
|
|
383
384
|
} finally {
|
|
384
|
-
ctx.
|
|
385
|
+
ctx.omega.isDevelopment = orig;
|
|
385
386
|
}
|
|
386
387
|
|
|
387
|
-
ctx.
|
|
388
|
+
ctx.omega.isDevelopment = () => false;
|
|
388
389
|
try {
|
|
389
|
-
ctx.
|
|
390
|
-
ctx.expect(ctx.
|
|
390
|
+
ctx.omega.menu.define(({ menu: m }) => m.useDefaults());
|
|
391
|
+
ctx.expect(ctx.omega.menu.has('view/developer/simulate-update')).toBe(false);
|
|
391
392
|
} finally {
|
|
392
|
-
ctx.
|
|
393
|
+
ctx.omega.isDevelopment = orig;
|
|
393
394
|
}
|
|
394
395
|
},
|
|
395
396
|
},
|
|
396
397
|
{
|
|
397
398
|
name: 'menu development top-level appears only in dev mode',
|
|
398
399
|
run: (ctx) => {
|
|
399
|
-
const orig = ctx.
|
|
400
|
-
ctx.
|
|
400
|
+
const orig = ctx.omega.isDevelopment;
|
|
401
|
+
ctx.omega.isDevelopment = () => true;
|
|
401
402
|
try {
|
|
402
|
-
ctx.
|
|
403
|
-
ctx.expect(ctx.
|
|
404
|
-
ctx.expect(ctx.
|
|
403
|
+
ctx.omega.menu.define(({ menu: m }) => m.useDefaults());
|
|
404
|
+
ctx.expect(ctx.omega.menu.has('development')).toBe(true);
|
|
405
|
+
ctx.expect(ctx.omega.menu.has('development/open-logs')).toBe(true);
|
|
405
406
|
} finally {
|
|
406
|
-
ctx.
|
|
407
|
+
ctx.omega.isDevelopment = orig;
|
|
407
408
|
}
|
|
408
409
|
|
|
409
|
-
ctx.
|
|
410
|
+
ctx.omega.isDevelopment = () => false;
|
|
410
411
|
try {
|
|
411
|
-
ctx.
|
|
412
|
-
ctx.expect(ctx.
|
|
412
|
+
ctx.omega.menu.define(({ menu: m }) => m.useDefaults());
|
|
413
|
+
ctx.expect(ctx.omega.menu.has('development')).toBe(false);
|
|
413
414
|
} finally {
|
|
414
|
-
ctx.
|
|
415
|
+
ctx.omega.isDevelopment = orig;
|
|
415
416
|
}
|
|
416
417
|
},
|
|
417
418
|
},
|