@omega.js/desktop 0.51.0 → 0.53.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 +18 -13
- 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.js +1 -1
- package/dist/commands/build.js +2 -2
- package/dist/commands/cdp/capture.js +2 -2
- 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/clean.js +2 -2
- package/dist/commands/deploy.js +4 -4
- package/dist/commands/finalize-release.js +4 -4
- package/dist/commands/install.js +3 -3
- package/dist/commands/launch.js +2 -2
- package/dist/commands/lib/deploy-precheck.js +3 -3
- package/dist/commands/lib/ensure-target.js +6 -6
- package/dist/commands/package.js +2 -2
- package/dist/commands/publish.js +2 -2
- package/dist/commands/release.js +3 -3
- package/dist/commands/runner.js +145 -48
- package/dist/commands/sign-windows.js +5 -5
- package/dist/commands/test.js +4 -4
- package/dist/commands/update.js +2 -2
- package/dist/commands/validate-certs.js +4 -4
- package/dist/commands/version.js +3 -3
- package/dist/defaults/.github/workflows/build.yml +2 -0
- package/dist/defaults/AGENTS.md +17 -8
- package/dist/defaults/config/omega.json5 +7 -7
- package/dist/defaults/hooks/build/post.js +1 -1
- package/dist/defaults/hooks/build/pre.js +1 -1
- package/dist/defaults/hooks/deploy/pre.js +1 -1
- package/dist/defaults/hooks/release/post.js +1 -1
- package/dist/defaults/hooks/release/pre.js +1 -1
- 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/integrations/context-menu/index.js +2 -2
- package/dist/defaults/src/integrations/menu/index.js +3 -3
- package/dist/defaults/src/integrations/tray/index.js +3 -3
- package/dist/defaults/src/main.js +3 -5
- package/dist/defaults/src/preload.js +3 -5
- package/dist/defaults/test/README.md +2 -2
- package/dist/gulp/main.js +9 -10
- package/dist/gulp/tasks/audit.js +7 -7
- 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 +28 -28
- 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 +398 -483
- package/dist/preload.js +236 -176
- package/dist/renderer.js +417 -391
- package/dist/runner/job-started.js +1 -1
- 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 +1 -1
- 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/cli.test.js +2 -2
- package/dist/test/suites/build/config-schema.test.js +5 -5
- package/dist/test/suites/build/defaults-scaffold.test.js +2 -2
- package/dist/test/suites/build/deploy-hook.test.js +3 -3
- package/dist/test/suites/build/ensure-target.test.js +2 -2
- 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 +1 -1
- 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/renderer-auth-bridge.test.js +211 -78
- package/dist/test/suites/build/runner.test.js +612 -5
- package/dist/test/suites/build/sentry.test.js +2 -2
- 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 +2 -2
- 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} +27 -7
- package/dist/test/utils/extended-mode-warning.js +1 -1
- package/dist/utils/boot-harness.js +56 -0
- package/dist/utils/mode-helpers.js +2 -15
- 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/environment.js +11 -30
- package/dist/vendor/config/index.js +13 -12
- package/dist/vendor/config/load.js +1 -2
- package/dist/vendor/config/platforms.js +1 -1
- package/dist/vendor/config/repo.js +24 -0
- package/dist/vendor/config/retired-keys.js +2 -2
- package/dist/vendor/config/schema.js +5 -8
- package/dist/vendor/config/site-global.js +2 -3
- package/dist/vendor/config/validate.js +1 -2
- package/dist/vendor/config/winback.js +1 -1
- package/dist/vendor/devkit/actions-secrets.js +1 -1
- package/dist/vendor/devkit/attach-log-file.js +1 -1
- package/dist/vendor/devkit/brand-version.js +162 -1
- package/dist/vendor/devkit/build-json.js +1 -1
- package/dist/vendor/devkit/cli-router.js +3 -4
- package/dist/vendor/devkit/defaults-engine.js +9 -11
- package/dist/vendor/devkit/deploy.js +64 -4
- package/dist/vendor/devkit/git-remote.js +78 -1
- package/dist/vendor/devkit/local.js +53 -3
- package/dist/vendor/devkit/lockfile.js +127 -0
- package/dist/vendor/devkit/merge-line-files.js +2 -3
- package/dist/vendor/devkit/pack-local.js +4 -7
- package/dist/vendor/devkit/preludes/origin-heal.js +35 -49
- package/dist/vendor/devkit/target-secrets.js +34 -45
- package/dist/vendor/devkit/test/runner-core.js +6 -6
- 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/docs/analytics.md +8 -8
- package/docs/app-state.md +19 -19
- package/docs/audit.md +4 -4
- package/docs/{client-bridge.md → auth.md} +88 -73
- package/docs/auto-updater.md +8 -8
- package/docs/boot-sequence.md +11 -6
- package/docs/build-system.md +1 -1
- package/docs/cdp-debugging.md +1 -1
- package/docs/common-mistakes.md +7 -7
- package/docs/config-schema.md +1 -1
- package/docs/context-menu.md +13 -13
- package/docs/context.md +11 -11
- package/docs/css.md +3 -9
- package/docs/deep-link.md +25 -25
- package/docs/environment-detection.md +16 -16
- package/docs/fontawesome.md +7 -5
- package/docs/hooks.md +8 -8
- package/docs/index.md +39 -28
- package/docs/ipc.md +10 -10
- package/docs/lib-modules.md +9 -9
- package/docs/logging.md +12 -14
- package/docs/menu.md +18 -18
- package/docs/releasing.md +4 -2
- package/docs/remote-config.md +9 -9
- package/docs/remote-scripts.md +12 -12
- package/docs/restart-manager.md +8 -8
- package/docs/runner.md +12 -10
- package/docs/sentry.md +4 -4
- package/docs/shared/analytics.md +1 -1
- package/docs/shared/brands.md +1 -1
- package/docs/shared/breaking-changes.md +79 -13
- package/docs/shared/config.md +24 -21
- package/docs/shared/deploys.md +30 -7
- package/docs/shared/local-dev.md +5 -3
- package/docs/shared/logging.md +1 -1
- package/docs/shared/monitoring.md +5 -5
- package/docs/shared/testing.md +2 -2
- package/docs/shared/theming.md +1 -1
- package/docs/shared/translation.md +19 -10
- package/docs/signing.md +1 -1
- package/docs/startup.md +16 -16
- package/docs/storage.md +11 -11
- package/docs/templating.md +3 -3
- package/docs/test-boot-layer.md +12 -12
- package/docs/test-framework.md +17 -17
- package/docs/themes.md +7 -7
- package/docs/tooltips.md +2 -2
- package/docs/tray.md +31 -31
- package/docs/usage.md +7 -7
- package/docs/verts.md +1 -1
- package/docs/windows.md +22 -22
- package/package.json +3 -4
- 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
|
@@ -16,12 +16,12 @@ module.exports = defineCases({
|
|
|
16
16
|
description: 'window-manager bounds persistence (main)',
|
|
17
17
|
cleanup: (ctx) => {
|
|
18
18
|
// Drop everything we wrote so reruns are clean.
|
|
19
|
-
ctx.
|
|
20
|
-
ctx.
|
|
21
|
-
ctx.
|
|
19
|
+
ctx.omega.storage.delete('windows.settings.bounds');
|
|
20
|
+
ctx.omega.storage.delete('windows.about.bounds');
|
|
21
|
+
ctx.omega.storage.delete('windows.bounds-test.bounds');
|
|
22
22
|
// Make sure no test-leftover windows remain.
|
|
23
23
|
['settings', 'about', 'bounds-test'].forEach((name) => {
|
|
24
|
-
const w = ctx.
|
|
24
|
+
const w = ctx.omega.windows.get(name);
|
|
25
25
|
if (w) {
|
|
26
26
|
w._emForceClose = true;
|
|
27
27
|
w.close();
|
|
@@ -32,33 +32,33 @@ module.exports = defineCases({
|
|
|
32
32
|
{
|
|
33
33
|
name: '_loadBounds returns null when nothing is saved',
|
|
34
34
|
run: (ctx) => {
|
|
35
|
-
ctx.
|
|
36
|
-
ctx.expect(ctx.
|
|
35
|
+
ctx.omega.storage.delete('windows.bounds-test.bounds');
|
|
36
|
+
ctx.expect(ctx.omega.windows._loadBounds('bounds-test', ctx.omega)).toBeNull();
|
|
37
37
|
},
|
|
38
38
|
},
|
|
39
39
|
{
|
|
40
40
|
name: '_loadBounds returns the saved object',
|
|
41
41
|
run: (ctx) => {
|
|
42
42
|
const saved = { x: 50, y: 60, width: 800, height: 600 };
|
|
43
|
-
ctx.
|
|
44
|
-
ctx.expect(ctx.
|
|
43
|
+
ctx.omega.storage.set('windows.bounds-test.bounds', saved);
|
|
44
|
+
ctx.expect(ctx.omega.windows._loadBounds('bounds-test', ctx.omega)).toEqual(saved);
|
|
45
45
|
},
|
|
46
46
|
},
|
|
47
47
|
{
|
|
48
48
|
name: '_loadBounds rejects malformed entries',
|
|
49
49
|
run: (ctx) => {
|
|
50
|
-
ctx.
|
|
51
|
-
ctx.expect(ctx.
|
|
50
|
+
ctx.omega.storage.set('windows.bounds-test.bounds', { width: 'oops' });
|
|
51
|
+
ctx.expect(ctx.omega.windows._loadBounds('bounds-test', ctx.omega)).toBeNull();
|
|
52
52
|
|
|
53
|
-
ctx.
|
|
54
|
-
ctx.expect(ctx.
|
|
53
|
+
ctx.omega.storage.set('windows.bounds-test.bounds', { width: 50, height: 50 }); // below sanity floor
|
|
54
|
+
ctx.expect(ctx.omega.windows._loadBounds('bounds-test', ctx.omega)).toBeNull();
|
|
55
55
|
},
|
|
56
56
|
},
|
|
57
57
|
{
|
|
58
58
|
name: '_clampToDisplays drops x/y when off-screen, keeps width/height',
|
|
59
59
|
run: (ctx) => {
|
|
60
60
|
// Way off-screen (huge negative coordinates).
|
|
61
|
-
const out = ctx.
|
|
61
|
+
const out = ctx.omega.windows._clampToDisplays({
|
|
62
62
|
x: -99999, y: -99999, width: 800, height: 600,
|
|
63
63
|
});
|
|
64
64
|
ctx.expect(out.x).toBeUndefined();
|
|
@@ -71,7 +71,7 @@ module.exports = defineCases({
|
|
|
71
71
|
name: '_clampToDisplays keeps x/y when on-screen',
|
|
72
72
|
run: (ctx) => {
|
|
73
73
|
// Use a primary-display point we know is on-screen: (100, 100).
|
|
74
|
-
const out = ctx.
|
|
74
|
+
const out = ctx.omega.windows._clampToDisplays({
|
|
75
75
|
x: 100, y: 100, width: 800, height: 600,
|
|
76
76
|
});
|
|
77
77
|
ctx.expect(out.x).toBe(100);
|
|
@@ -83,9 +83,9 @@ module.exports = defineCases({
|
|
|
83
83
|
run: async (ctx) => {
|
|
84
84
|
// Pre-seed storage with bounds for the about window.
|
|
85
85
|
const wanted = { x: 120, y: 140, width: 720, height: 540 };
|
|
86
|
-
ctx.
|
|
86
|
+
ctx.omega.storage.set('windows.about.bounds', wanted);
|
|
87
87
|
|
|
88
|
-
const win = await ctx.
|
|
88
|
+
const win = await ctx.omega.windows.createNamed('about');
|
|
89
89
|
ctx.state.win = win;
|
|
90
90
|
const got = win.getBounds();
|
|
91
91
|
ctx.expect(got.width).toBe(720);
|
|
@@ -103,9 +103,9 @@ module.exports = defineCases({
|
|
|
103
103
|
|
|
104
104
|
// Move + resize, then trigger save.
|
|
105
105
|
win.setBounds({ x: 200, y: 220, width: 640, height: 480 });
|
|
106
|
-
ctx.
|
|
106
|
+
ctx.omega.windows._saveBoundsNow('about');
|
|
107
107
|
|
|
108
|
-
const saved = ctx.
|
|
108
|
+
const saved = ctx.omega.storage.get('windows.about.bounds');
|
|
109
109
|
ctx.expect(saved).toBeTruthy();
|
|
110
110
|
ctx.expect(saved.width).toBe(640);
|
|
111
111
|
ctx.expect(saved.height).toBe(480);
|
|
@@ -123,10 +123,10 @@ module.exports = defineCases({
|
|
|
123
123
|
if (win.isDestroyed()) return r();
|
|
124
124
|
win.once('closed', r);
|
|
125
125
|
});
|
|
126
|
-
ctx.
|
|
126
|
+
ctx.omega.windows.close('about');
|
|
127
127
|
await closedPromise;
|
|
128
128
|
|
|
129
|
-
const saved = ctx.
|
|
129
|
+
const saved = ctx.omega.storage.get('windows.about.bounds');
|
|
130
130
|
ctx.expect(saved.width).toBe(555);
|
|
131
131
|
ctx.expect(saved.height).toBe(444);
|
|
132
132
|
},
|
|
@@ -135,13 +135,13 @@ module.exports = defineCases({
|
|
|
135
135
|
name: 'persistBounds: false → no auto-save on resize, no restore on create',
|
|
136
136
|
run: async (ctx) => {
|
|
137
137
|
// Pre-seed bounds that SHOULD be ignored when persistBounds: false.
|
|
138
|
-
ctx.
|
|
138
|
+
ctx.omega.storage.set('windows.about.bounds', { x: 50, y: 60, width: 999, height: 888 });
|
|
139
139
|
|
|
140
140
|
// The `windows` config block is no longer required — pass persistBounds via the
|
|
141
141
|
// call-site overrides arg instead. (The merge order is defaults < JSON config <
|
|
142
142
|
// overrides, so this works whether or not config.windows.about is set.)
|
|
143
143
|
try {
|
|
144
|
-
const win = await ctx.
|
|
144
|
+
const win = await ctx.omega.windows.createNamed('about', undefined, { persistBounds: false });
|
|
145
145
|
|
|
146
146
|
// Saved 999x888 must NOT have been restored — should fall back to config defaults.
|
|
147
147
|
const got = win.getBounds();
|
|
@@ -149,19 +149,19 @@ module.exports = defineCases({
|
|
|
149
149
|
ctx.expect(got.height).not.toBe(888);
|
|
150
150
|
|
|
151
151
|
// Now resize and confirm no auto-save fires past the debounce window.
|
|
152
|
-
ctx.
|
|
152
|
+
ctx.omega.storage.delete('windows.about.bounds');
|
|
153
153
|
win.setBounds({ x: 30, y: 30, width: 700, height: 500 });
|
|
154
154
|
await new Promise((r) => setTimeout(r, 350));
|
|
155
|
-
ctx.expect(ctx.
|
|
155
|
+
ctx.expect(ctx.omega.storage.get('windows.about.bounds')).toBeUndefined();
|
|
156
156
|
|
|
157
157
|
const closedPromise = new Promise((r) => win.once('closed', r));
|
|
158
|
-
ctx.
|
|
158
|
+
ctx.omega.windows.close('about');
|
|
159
159
|
await closedPromise;
|
|
160
160
|
|
|
161
161
|
// close also must NOT have written under persistBounds:false.
|
|
162
|
-
ctx.expect(ctx.
|
|
162
|
+
ctx.expect(ctx.omega.storage.get('windows.about.bounds')).toBeUndefined();
|
|
163
163
|
} finally {
|
|
164
|
-
ctx.
|
|
164
|
+
ctx.omega.storage.delete('windows.about.bounds');
|
|
165
165
|
}
|
|
166
166
|
},
|
|
167
167
|
},
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
//
|
|
3
3
|
// Note: createNamed requires src/views/<view>/index.html to exist on disk in the test cwd.
|
|
4
4
|
// The harness uses @omega.js/desktop's defaults config but runs from @omega.js/desktop's repo root, where there are no built views.
|
|
5
|
-
// So we test the API surface and dedup behavior using the
|
|
5
|
+
// So we test the API surface and dedup behavior using the omega instance's electron handle but skip
|
|
6
6
|
// actual file-loading in createNamed (it logs an error and returns the BrowserWindow anyway,
|
|
7
7
|
// which is enough to verify the registry behavior).
|
|
8
8
|
|
|
@@ -16,21 +16,21 @@ module.exports = defineCases({
|
|
|
16
16
|
{
|
|
17
17
|
name: 'initialize was called during boot',
|
|
18
18
|
run: (ctx) => {
|
|
19
|
-
ctx.expect(ctx.
|
|
19
|
+
ctx.expect(ctx.omega.windows._initialized).toBe(true);
|
|
20
20
|
},
|
|
21
21
|
},
|
|
22
22
|
{
|
|
23
23
|
name: 'list returns empty array when no windows are open',
|
|
24
24
|
run: (ctx) => {
|
|
25
25
|
// skipWindowCreation: true means no window was auto-created.
|
|
26
|
-
ctx.expect(Array.isArray(ctx.
|
|
27
|
-
ctx.expect(ctx.
|
|
26
|
+
ctx.expect(Array.isArray(ctx.omega.windows.list())).toBe(true);
|
|
27
|
+
ctx.expect(ctx.omega.windows.list().length).toBe(0);
|
|
28
28
|
},
|
|
29
29
|
},
|
|
30
30
|
{
|
|
31
31
|
name: 'get returns null for unknown name',
|
|
32
32
|
run: (ctx) => {
|
|
33
|
-
ctx.expect(ctx.
|
|
33
|
+
ctx.expect(ctx.omega.windows.get('nonexistent')).toBeNull();
|
|
34
34
|
},
|
|
35
35
|
},
|
|
36
36
|
{
|
|
@@ -39,25 +39,25 @@ module.exports = defineCases({
|
|
|
39
39
|
// We need a view file. Use @omega.js/desktop's own defaults dir as the cwd-equivalent by setting a custom html path.
|
|
40
40
|
// For simplicity, just verify createNamed creates a BrowserWindow even when the html file is missing
|
|
41
41
|
// (loadFile catches the error; the window object still exists in the registry).
|
|
42
|
-
const win = await ctx.
|
|
42
|
+
const win = await ctx.omega.windows.createNamed('about');
|
|
43
43
|
ctx.state.win = win;
|
|
44
44
|
ctx.expect(win).toBeTruthy();
|
|
45
|
-
ctx.expect(ctx.
|
|
46
|
-
ctx.expect(ctx.
|
|
45
|
+
ctx.expect(ctx.omega.windows.get('about')).toBe(win);
|
|
46
|
+
ctx.expect(ctx.omega.windows.list()).toContain('about');
|
|
47
47
|
},
|
|
48
48
|
},
|
|
49
49
|
{
|
|
50
50
|
name: 'createNamed dedups — second call returns the same window',
|
|
51
51
|
run: async (ctx) => {
|
|
52
|
-
const again = await ctx.
|
|
52
|
+
const again = await ctx.omega.windows.createNamed('about');
|
|
53
53
|
ctx.expect(again).toBe(ctx.state.win);
|
|
54
54
|
},
|
|
55
55
|
},
|
|
56
56
|
{
|
|
57
57
|
name: 'hide / show do not throw',
|
|
58
58
|
run: (ctx) => {
|
|
59
|
-
ctx.
|
|
60
|
-
ctx.
|
|
59
|
+
ctx.omega.windows.hide('about');
|
|
60
|
+
ctx.omega.windows.show('about');
|
|
61
61
|
// No assertion beyond "didn't throw" — visibility is OS-side state we can't reliably read.
|
|
62
62
|
},
|
|
63
63
|
},
|
|
@@ -66,13 +66,13 @@ module.exports = defineCases({
|
|
|
66
66
|
// without a startup block (schema: optional) threw inside the hide handler.
|
|
67
67
|
name: '_maybeRehideDock survives a config without a startup block',
|
|
68
68
|
run: (ctx) => {
|
|
69
|
-
const orig = ctx.
|
|
70
|
-
delete ctx.
|
|
69
|
+
const orig = ctx.omega.config.startup;
|
|
70
|
+
delete ctx.omega.config.startup;
|
|
71
71
|
try {
|
|
72
|
-
ctx.
|
|
73
|
-
ctx.expect(ctx.
|
|
72
|
+
ctx.omega.windows._maybeRehideDock(); // must not throw
|
|
73
|
+
ctx.expect(ctx.omega.startup.getMode()).toBe('normal');
|
|
74
74
|
} finally {
|
|
75
|
-
if (orig !== undefined) ctx.
|
|
75
|
+
if (orig !== undefined) ctx.omega.config.startup = orig;
|
|
76
76
|
}
|
|
77
77
|
},
|
|
78
78
|
},
|
|
@@ -84,7 +84,7 @@ module.exports = defineCases({
|
|
|
84
84
|
if (process.platform !== 'darwin') {
|
|
85
85
|
return ctx.skip('macOS-only — accessory activation policy / dock');
|
|
86
86
|
}
|
|
87
|
-
// Both the harness entry (at require time) and
|
|
87
|
+
// Both the harness entry (at require time) and omega.initialize() (step 1a)
|
|
88
88
|
// hide the dock under the stealth predicate, so the launched test app never
|
|
89
89
|
// activates and never steals keyboard focus.
|
|
90
90
|
const { app } = require('electron');
|
|
@@ -96,10 +96,10 @@ module.exports = defineCases({
|
|
|
96
96
|
run: (ctx) => {
|
|
97
97
|
const { BrowserWindow } = require('electron');
|
|
98
98
|
|
|
99
|
-
ctx.expect(ctx.
|
|
99
|
+
ctx.expect(ctx.omega.windows._isStealth()).toBe(true);
|
|
100
100
|
|
|
101
101
|
const win = new BrowserWindow({ show: false, width: 120, height: 80 });
|
|
102
|
-
ctx.
|
|
102
|
+
ctx.omega.windows._surface(win, 'stealth-probe');
|
|
103
103
|
|
|
104
104
|
// Shown (rendering/timers run like a visible window — NOT hide/minimize,
|
|
105
105
|
// which would occlusion-throttle) but fully transparent and inactive.
|
|
@@ -117,7 +117,7 @@ module.exports = defineCases({
|
|
|
117
117
|
|
|
118
118
|
process.env.OMEGA_TEST_SHOW = '1';
|
|
119
119
|
try {
|
|
120
|
-
ctx.expect(ctx.
|
|
120
|
+
ctx.expect(ctx.omega.windows._isStealth()).toBe(false);
|
|
121
121
|
|
|
122
122
|
// This probe exercises the real non-stealth _surface branch WITHOUT
|
|
123
123
|
// stealing the developer's keyboard focus mid-run. Two activation
|
|
@@ -133,7 +133,7 @@ module.exports = defineCases({
|
|
|
133
133
|
require('electron').app.setActivationPolicy('regular');
|
|
134
134
|
}
|
|
135
135
|
const win = new BrowserWindow({ show: false, width: 120, height: 80, x: 0, y: 0, focusable: false });
|
|
136
|
-
ctx.
|
|
136
|
+
ctx.omega.windows._surface(win, 'visible-probe');
|
|
137
137
|
|
|
138
138
|
ctx.expect(win.isVisible()).toBe(true);
|
|
139
139
|
ctx.expect(win.getOpacity()).toBe(1);
|
|
@@ -148,7 +148,7 @@ module.exports = defineCases({
|
|
|
148
148
|
}
|
|
149
149
|
|
|
150
150
|
// Flag removed → stealth is back on for the rest of the run.
|
|
151
|
-
ctx.expect(ctx.
|
|
151
|
+
ctx.expect(ctx.omega.windows._isStealth()).toBe(true);
|
|
152
152
|
},
|
|
153
153
|
},
|
|
154
154
|
{
|
|
@@ -158,7 +158,7 @@ module.exports = defineCases({
|
|
|
158
158
|
return; // trafficLightPosition is a macOS-only BrowserWindow option
|
|
159
159
|
}
|
|
160
160
|
|
|
161
|
-
const win = await ctx.
|
|
161
|
+
const win = await ctx.omega.windows.create('tlp-probe', { trafficLightPosition: { x: 26, y: 24 } });
|
|
162
162
|
ctx.expect(win).toBeTruthy();
|
|
163
163
|
|
|
164
164
|
const pos = win.getWindowButtonPosition();
|
|
@@ -170,7 +170,7 @@ module.exports = defineCases({
|
|
|
170
170
|
{
|
|
171
171
|
name: 'close removes the window from the registry',
|
|
172
172
|
run: async (ctx) => {
|
|
173
|
-
const win = ctx.
|
|
173
|
+
const win = ctx.omega.windows.get('about');
|
|
174
174
|
ctx.expect(win).toBeTruthy();
|
|
175
175
|
|
|
176
176
|
// close fires asynchronously — wait for the 'closed' event rather than guessing a timeout.
|
|
@@ -179,18 +179,18 @@ module.exports = defineCases({
|
|
|
179
179
|
win.once('closed', resolve);
|
|
180
180
|
});
|
|
181
181
|
|
|
182
|
-
ctx.
|
|
182
|
+
ctx.omega.windows.close('about');
|
|
183
183
|
await closedPromise;
|
|
184
184
|
|
|
185
|
-
ctx.expect(ctx.
|
|
185
|
+
ctx.expect(ctx.omega.windows.get('about')).toBeNull();
|
|
186
186
|
},
|
|
187
187
|
},
|
|
188
188
|
{
|
|
189
|
-
name: '
|
|
189
|
+
name: 'omega.quit + omega.relaunch exposed and set _allowQuit',
|
|
190
190
|
run: (ctx) => {
|
|
191
|
-
ctx.expect(typeof ctx.
|
|
192
|
-
ctx.expect(typeof ctx.
|
|
193
|
-
ctx.
|
|
191
|
+
ctx.expect(typeof ctx.omega.quit).toBe('function');
|
|
192
|
+
ctx.expect(typeof ctx.omega.relaunch).toBe('function');
|
|
193
|
+
ctx.omega._allowQuit = false;
|
|
194
194
|
|
|
195
195
|
// Calling quit({force:true}) should set _allowQuit BEFORE invoking app.quit().
|
|
196
196
|
// We can't actually let app.quit() run mid-test (it'd kill the harness), so we
|
|
@@ -199,33 +199,33 @@ module.exports = defineCases({
|
|
|
199
199
|
const origQuit = electron.app.quit;
|
|
200
200
|
electron.app.quit = () => {};
|
|
201
201
|
try {
|
|
202
|
-
ctx.
|
|
203
|
-
ctx.expect(ctx.
|
|
202
|
+
ctx.omega.quit({ force: true });
|
|
203
|
+
ctx.expect(ctx.omega._allowQuit).toBe(true);
|
|
204
204
|
} finally {
|
|
205
205
|
electron.app.quit = origQuit;
|
|
206
|
-
ctx.
|
|
206
|
+
ctx.omega._allowQuit = false;
|
|
207
207
|
}
|
|
208
208
|
},
|
|
209
209
|
},
|
|
210
210
|
{
|
|
211
|
-
name: 'auto-updater installNow flips
|
|
211
|
+
name: 'auto-updater installNow flips omega._allowQuit',
|
|
212
212
|
run: (ctx) => {
|
|
213
|
-
ctx.
|
|
213
|
+
ctx.omega._allowQuit = false;
|
|
214
214
|
|
|
215
215
|
// Force the autoUpdater state to "downloaded" + stub the underlying library
|
|
216
216
|
// so installNow doesn't actually quit the harness.
|
|
217
|
-
const prevState = ctx.
|
|
218
|
-
const prevLib = ctx.
|
|
219
|
-
ctx.
|
|
220
|
-
ctx.
|
|
217
|
+
const prevState = ctx.omega.autoUpdater._state;
|
|
218
|
+
const prevLib = ctx.omega.autoUpdater._library;
|
|
219
|
+
ctx.omega.autoUpdater._state = { code: 'downloaded', version: '9.9.9' };
|
|
220
|
+
ctx.omega.autoUpdater._library = { quitAndInstall: () => {} };
|
|
221
221
|
|
|
222
222
|
try {
|
|
223
|
-
ctx.
|
|
224
|
-
ctx.expect(ctx.
|
|
223
|
+
ctx.omega.autoUpdater.installNow();
|
|
224
|
+
ctx.expect(ctx.omega._allowQuit).toBe(true);
|
|
225
225
|
} finally {
|
|
226
|
-
ctx.
|
|
227
|
-
ctx.
|
|
228
|
-
ctx.
|
|
226
|
+
ctx.omega.autoUpdater._state = prevState;
|
|
227
|
+
ctx.omega.autoUpdater._library = prevLib;
|
|
228
|
+
ctx.omega._allowQuit = false;
|
|
229
229
|
}
|
|
230
230
|
},
|
|
231
231
|
},
|
|
@@ -38,15 +38,15 @@ module.exports = defineCases({
|
|
|
38
38
|
},
|
|
39
39
|
},
|
|
40
40
|
{
|
|
41
|
-
// #411: a renderer's own `omega.analytics
|
|
41
|
+
// #411: a renderer's own `omega.analytics.event(...)` used to no-op
|
|
42
42
|
// silently — the embedded client had no way to deliver. It now forwards
|
|
43
43
|
// over this bridge, and main's sender is the one that fires it.
|
|
44
|
-
name: 'a renderer-originated omega.analytics
|
|
44
|
+
name: 'a renderer-originated omega.analytics event reaches main\'s sender exactly once, with main\'s identity',
|
|
45
45
|
run: async (ctx) => {
|
|
46
46
|
const read = () => window.desktop.ipc.invoke('desktop:__test:read-analytics-sends');
|
|
47
47
|
const baseline = (await read()).length;
|
|
48
48
|
|
|
49
|
-
window.
|
|
49
|
+
window.__omegaTestClientAnalytics.event('vert_click', { vert_id: 'pin-411' });
|
|
50
50
|
|
|
51
51
|
// The forward is fire-and-forget IPC — poll until main records it.
|
|
52
52
|
let sends = [];
|
|
@@ -54,7 +54,7 @@ module.exports = defineCases({
|
|
|
54
54
|
while (sends.length <= baseline) {
|
|
55
55
|
// The client's own state says WHY when this fails: an unbridged one
|
|
56
56
|
// carries a client id of its own — the identity fork (#411).
|
|
57
|
-
if (Date.now() - t0 > 3000) throw new Error(`timed out waiting for main to record the forwarded event
|
|
57
|
+
if (Date.now() - t0 > 3000) throw new Error(`timed out waiting for main to record the forwarded event, client state ${JSON.stringify(window.__omegaTestClientAnalytics.state())}`);
|
|
58
58
|
await new Promise((r) => setTimeout(r, 25));
|
|
59
59
|
sends = await read();
|
|
60
60
|
}
|
|
@@ -79,7 +79,7 @@ module.exports = defineCases({
|
|
|
79
79
|
{
|
|
80
80
|
name: 'the bridged renderer holds no sender of its own — no secret, no second device id',
|
|
81
81
|
run: (ctx) => {
|
|
82
|
-
const state = window.
|
|
82
|
+
const state = window.__omegaTestClientAnalytics.state();
|
|
83
83
|
ctx.expect(state.initialized).toBe(true);
|
|
84
84
|
ctx.expect(state.bridged).toBe(true);
|
|
85
85
|
ctx.expect(state.secret).toBe(null);
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
// Renderer-layer tests for the cross-context helpers
|
|
2
|
-
//
|
|
3
|
-
//
|
|
1
|
+
// Renderer-layer tests for the cross-context helpers on the renderer `omega`
|
|
2
|
+
// instance: `isDevelopment / isProduction / isTesting / getEnvironment` and
|
|
3
|
+
// `getApiUrl / getFunctionsUrl` (the @omega.js/client base class's own), plus
|
|
4
|
+
// desktop's `getVersion / getWebsiteUrl` (utils/mode-helpers + utils/url-helpers),
|
|
4
5
|
// end-to-end inside a real renderer process, not just in main.
|
|
5
6
|
//
|
|
6
|
-
// The renderer-preload (test/harness/renderer-preload.js)
|
|
7
|
-
//
|
|
7
|
+
// The renderer-preload (test/harness/renderer-preload.js) builds the real renderer
|
|
8
|
+
// instance and exposes its helpers via contextBridge as `window.__omegaTestInstance`.
|
|
8
9
|
// Test bodies are stringified + reconstructed via `new Function('ctx', body)` so
|
|
9
|
-
// they only have access to `ctx` and `window
|
|
10
|
+
// they only have access to `ctx` and `window`, no closures over module scope.
|
|
10
11
|
|
|
11
12
|
const defineCases = require('../../../vendor/devkit/test/define-cases.js');
|
|
12
13
|
|
|
@@ -16,16 +17,19 @@ module.exports = defineCases({
|
|
|
16
17
|
description: 'cross-context helpers (renderer)',
|
|
17
18
|
tests: [
|
|
18
19
|
{
|
|
19
|
-
name: '
|
|
20
|
+
name: '__omegaTestInstance is exposed by the test preload, over a built instance',
|
|
20
21
|
run: (ctx) => {
|
|
21
|
-
ctx.expect(typeof window.
|
|
22
|
-
ctx.expect(window.
|
|
22
|
+
ctx.expect(typeof window.__omegaTestInstance).toBe('object');
|
|
23
|
+
ctx.expect(window.__omegaTestInstance).toBeTruthy();
|
|
24
|
+
if (!window.__omegaTestInstance.built()) {
|
|
25
|
+
throw new Error(`the renderer instance did not build: ${window.__omegaTestInstance.error()}`);
|
|
26
|
+
}
|
|
23
27
|
},
|
|
24
28
|
},
|
|
25
29
|
{
|
|
26
30
|
name: 'isTesting() returns true (this lane named OMEGA_ENVIRONMENT=testing)',
|
|
27
31
|
run: (ctx) => {
|
|
28
|
-
ctx.expect(window.
|
|
32
|
+
ctx.expect(window.__omegaTestInstance.isTesting()).toBe(true);
|
|
29
33
|
},
|
|
30
34
|
},
|
|
31
35
|
{
|
|
@@ -34,7 +38,7 @@ module.exports = defineCases({
|
|
|
34
38
|
// Nothing here reads app.isPackaged or NODE_ENV any more (#817): the
|
|
35
39
|
// preload has a process, so the lane's OMEGA_ENVIRONMENT answers, and a
|
|
36
40
|
// real renderer bundle answers from the baked config.environment.
|
|
37
|
-
const v = window.
|
|
41
|
+
const v = window.__omegaTestInstance.isDevelopment();
|
|
38
42
|
ctx.expect(typeof v).toBe('boolean');
|
|
39
43
|
ctx.expect(v).toBe(false);
|
|
40
44
|
},
|
|
@@ -42,9 +46,9 @@ module.exports = defineCases({
|
|
|
42
46
|
{
|
|
43
47
|
name: 'environments are mutually exclusive — exactly one of dev/testing/prod is true',
|
|
44
48
|
run: (ctx) => {
|
|
45
|
-
const dev = window.
|
|
46
|
-
const test = window.
|
|
47
|
-
const prod = window.
|
|
49
|
+
const dev = window.__omegaTestInstance.isDevelopment();
|
|
50
|
+
const test = window.__omegaTestInstance.isTesting();
|
|
51
|
+
const prod = window.__omegaTestInstance.isProduction();
|
|
48
52
|
// This lane named testing; dev and prod are both false.
|
|
49
53
|
ctx.expect(test).toBe(true);
|
|
50
54
|
ctx.expect(dev).toBe(false);
|
|
@@ -55,7 +59,7 @@ module.exports = defineCases({
|
|
|
55
59
|
{
|
|
56
60
|
name: 'getVersion() returns a string or null without throwing',
|
|
57
61
|
run: (ctx) => {
|
|
58
|
-
const v = window.
|
|
62
|
+
const v = window.__omegaTestInstance.getVersion();
|
|
59
63
|
// In renderer, `electron.app` is unavailable and process.cwd()/package.json
|
|
60
64
|
// resolves to whatever the test harness was launched from — could be either
|
|
61
65
|
// a string or null. Assert just the shape.
|
|
@@ -69,32 +73,34 @@ module.exports = defineCases({
|
|
|
69
73
|
// process to read it from, so it wins over whatever the artifact was
|
|
70
74
|
// baked as (#817). A real renderer bundle has no process and takes the
|
|
71
75
|
// baked word, which is the other half of the same one-input rule.
|
|
72
|
-
window.
|
|
73
|
-
ctx.expect(window.
|
|
74
|
-
window.
|
|
75
|
-
ctx.expect(window.
|
|
76
|
+
window.__omegaTestInstance.setConfig('environment', 'production');
|
|
77
|
+
ctx.expect(window.__omegaTestInstance.getEnvironment()).toBe('testing');
|
|
78
|
+
window.__omegaTestInstance.setConfig('environment', 'development');
|
|
79
|
+
ctx.expect(window.__omegaTestInstance.getEnvironment()).toBe('testing');
|
|
76
80
|
// Reset.
|
|
77
|
-
window.
|
|
81
|
+
window.__omegaTestInstance.setConfig('environment', 'production');
|
|
78
82
|
},
|
|
79
83
|
},
|
|
80
84
|
{
|
|
81
85
|
name: 'getFunctionsUrl: dev → localhost:5001/<projectId>/us-central1',
|
|
82
86
|
run: (ctx) => {
|
|
83
|
-
ctx.expect(window.
|
|
87
|
+
ctx.expect(window.__omegaTestInstance.getFunctionsUrl('development'))
|
|
84
88
|
.toBe('http://localhost:5001/demo-app/us-central1');
|
|
85
89
|
},
|
|
86
90
|
},
|
|
87
91
|
{
|
|
88
92
|
name: 'getFunctionsUrl: prod → us-central1-<projectId>.cloudfunctions.net',
|
|
89
93
|
run: (ctx) => {
|
|
90
|
-
ctx.expect(window.
|
|
94
|
+
ctx.expect(window.__omegaTestInstance.getFunctionsUrl('production'))
|
|
91
95
|
.toBe('https://us-central1-demo-app.cloudfunctions.net');
|
|
92
96
|
},
|
|
93
97
|
},
|
|
94
98
|
{
|
|
95
|
-
|
|
99
|
+
// The client's own getApiUrl, the one `omega.request()` calls: a baked
|
|
100
|
+
// `hosting` port with no `https` one is the emulator on 127.0.0.1
|
|
101
|
+
name: 'getApiUrl: dev → http://127.0.0.1:5002 (the client base class answers)',
|
|
96
102
|
run: (ctx) => {
|
|
97
|
-
ctx.expect(window.
|
|
103
|
+
ctx.expect(window.__omegaTestInstance.getApiUrl('development')).toBe('http://127.0.0.1:5002');
|
|
98
104
|
},
|
|
99
105
|
},
|
|
100
106
|
{
|
|
@@ -102,20 +108,20 @@ module.exports = defineCases({
|
|
|
102
108
|
// authDomain — that value is an auth-only concern.
|
|
103
109
|
name: 'getApiUrl: prod → api.<brand.url host>',
|
|
104
110
|
run: (ctx) => {
|
|
105
|
-
ctx.expect(window.
|
|
111
|
+
ctx.expect(window.__omegaTestInstance.getApiUrl('production'))
|
|
106
112
|
.toBe('https://api.example.com');
|
|
107
113
|
},
|
|
108
114
|
},
|
|
109
115
|
{
|
|
110
116
|
name: 'getWebsiteUrl: dev → https://localhost:4000, from the baked classic map',
|
|
111
117
|
run: (ctx) => {
|
|
112
|
-
ctx.expect(window.
|
|
118
|
+
ctx.expect(window.__omegaTestInstance.getWebsiteUrl('development')).toBe('https://localhost:4000');
|
|
113
119
|
},
|
|
114
120
|
},
|
|
115
121
|
{
|
|
116
122
|
name: 'getWebsiteUrl: prod → config.brand.url',
|
|
117
123
|
run: (ctx) => {
|
|
118
|
-
ctx.expect(window.
|
|
124
|
+
ctx.expect(window.__omegaTestInstance.getWebsiteUrl('production')).toBe('https://example.com');
|
|
119
125
|
},
|
|
120
126
|
},
|
|
121
127
|
{
|
|
@@ -123,11 +129,11 @@ module.exports = defineCases({
|
|
|
123
129
|
run: (ctx) => {
|
|
124
130
|
// This lane is testing, so the no-arg form resolves LOCAL regardless of
|
|
125
131
|
// what the artifact was baked as: that's the safety guarantee.
|
|
126
|
-
window.
|
|
127
|
-
ctx.expect(window.
|
|
132
|
+
window.__omegaTestInstance.setConfig('environment', 'production');
|
|
133
|
+
ctx.expect(window.__omegaTestInstance.getWebsiteUrl()).toBe('https://localhost:4000');
|
|
128
134
|
// An explicit env arg bypasses the current environment and pins the mapping.
|
|
129
|
-
ctx.expect(window.
|
|
130
|
-
ctx.expect(window.
|
|
135
|
+
ctx.expect(window.__omegaTestInstance.getWebsiteUrl('production')).toBe('https://example.com');
|
|
136
|
+
ctx.expect(window.__omegaTestInstance.getWebsiteUrl('development')).toBe('https://localhost:4000');
|
|
131
137
|
},
|
|
132
138
|
},
|
|
133
139
|
],
|
|
@@ -37,7 +37,7 @@ module.exports = defineCases({
|
|
|
37
37
|
{
|
|
38
38
|
name: 'window.desktop.logger.log forwards to main where it can be read back',
|
|
39
39
|
run: async (ctx) => {
|
|
40
|
-
const marker = `
|
|
40
|
+
const marker = `__omega_test_log_${Date.now()}_${Math.random()}`;
|
|
41
41
|
window.desktop.logger.log(marker, { extra: 'payload' });
|
|
42
42
|
// Give main a moment to receive (IPC send is async, no callback).
|
|
43
43
|
await new Promise((r) => setTimeout(r, 50));
|
|
@@ -53,7 +53,7 @@ module.exports = defineCases({
|
|
|
53
53
|
{
|
|
54
54
|
name: 'window.desktop.logger.warn also forwards',
|
|
55
55
|
run: async (ctx) => {
|
|
56
|
-
const marker = `
|
|
56
|
+
const marker = `__omega_test_warn_${Date.now()}_${Math.random()}`;
|
|
57
57
|
window.desktop.logger.warn(marker);
|
|
58
58
|
await new Promise((r) => setTimeout(r, 50));
|
|
59
59
|
const last = await window.desktop.ipc.invoke('desktop:__test:read-last-log');
|
|
@@ -65,7 +65,7 @@ module.exports = defineCases({
|
|
|
65
65
|
name: 'window.desktop.storage.set → window.desktop.storage.onChange fires across IPC',
|
|
66
66
|
run: async (ctx) => {
|
|
67
67
|
// Subscribe FIRST so we don't miss the broadcast.
|
|
68
|
-
const key = `
|
|
68
|
+
const key = `__omega_renderer_change_${Date.now()}`;
|
|
69
69
|
let received = null;
|
|
70
70
|
const off = window.desktop.storage.onChange(key, (payload) => { received = payload; });
|
|
71
71
|
try {
|