pinokiod 7.5.44 → 7.5.45
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/package.json +1 -1
- package/server/index.js +403 -24
- package/server/public/style.css +0 -264
- package/server/public/urldropdown.css +7 -0
- package/server/views/app.ejs +2 -0
- package/server/views/app_search_test.ejs +2 -0
- package/server/views/connect/x.ejs +2 -0
- package/server/views/container.ejs +2 -0
- package/server/views/create.ejs +3 -0
- package/server/views/editor.ejs +3 -0
- package/server/views/env_editor.ejs +2 -0
- package/server/views/explore.ejs +2 -0
- package/server/views/general_editor.ejs +3 -0
- package/server/views/help.ejs +2 -0
- package/server/views/index.ejs +539 -2
- package/server/views/init/index.ejs +2 -0
- package/server/views/keys.ejs +2 -0
- package/server/views/mini.ejs +2 -0
- package/server/views/net.ejs +2 -0
- package/server/views/network.ejs +887 -94
- package/server/views/partials/app_navheader.ejs +2 -0
- package/server/views/partials/home_action_modal.ejs +22 -0
- package/server/views/partials/home_server_popover.ejs +21 -0
- package/server/views/partials/home_server_popover_assets.ejs +1262 -0
- package/server/views/partials/main_sidebar.ejs +1 -221
- package/server/views/pro.ejs +7 -0
- package/server/views/prototype/index.ejs +2 -0
- package/server/views/review.ejs +2 -0
- package/server/views/screenshots.ejs +2 -0
- package/server/views/settings.ejs +2 -0
- package/server/views/shell.ejs +7 -0
- package/server/views/task.ejs +2 -0
- package/server/views/terminal.ejs +2 -0
- package/server/views/terminals.ejs +2 -0
- package/test/launch-settings-ui.test.js +355 -0
- package/test/main-sidebar.test.js +26 -16
|
@@ -4,6 +4,7 @@ const path = require("node:path")
|
|
|
4
4
|
const test = require("node:test")
|
|
5
5
|
const ejs = require("ejs")
|
|
6
6
|
const { JSDOM } = require("jsdom")
|
|
7
|
+
const Server = require("../server")
|
|
7
8
|
|
|
8
9
|
const root = path.resolve(__dirname, "..")
|
|
9
10
|
|
|
@@ -415,6 +416,360 @@ test("home actions modal renders an app settings link", async () => {
|
|
|
415
416
|
assert.match(html, />\s*Settings\s*</)
|
|
416
417
|
})
|
|
417
418
|
|
|
419
|
+
test("home exposes Home Server app sharing from row and action drawer", async () => {
|
|
420
|
+
const homeView = await fs.readFile(path.resolve(root, "server/views/index.ejs"), "utf8")
|
|
421
|
+
const homeActionModal = await fs.readFile(path.resolve(root, "server/views/partials/home_action_modal.ejs"), "utf8")
|
|
422
|
+
const server = await fs.readFile(path.resolve(root, "server/index.js"), "utf8")
|
|
423
|
+
|
|
424
|
+
assert.match(server, /ready_url: readyUrl/)
|
|
425
|
+
assert.match(server, /external_ready_urls: externalReadyUrls/)
|
|
426
|
+
assert.match(server, /this\.appRegistry\.buildExternalReadyUrls\(readyUrl\)/)
|
|
427
|
+
assert.match(server, /findHomeShareReadyUrlFromMenu\(menu = \[\]\)/)
|
|
428
|
+
assert.match(server, /readyUrl = this\.findHomeShareReadyUrlFromMenu\(x\.menu\)/)
|
|
429
|
+
assert.match(homeView, /class='btn home-icon-btn open-app-share-modal'/)
|
|
430
|
+
assert.match(homeView, /fa-solid fa-wifi/)
|
|
431
|
+
assert.match(homeView, /data-app-id="<%= item\.uri %>"/)
|
|
432
|
+
assert.match(homeView, /data-app-external-ready-urls="<%= JSON\.stringify\(runningShareExternalReadyUrls\) %>"/)
|
|
433
|
+
assert.match(homeView, /const requestHomeAppShareStatus = async \(appId = ""\) =>/)
|
|
434
|
+
assert.match(homeView, /fetch\(`\/apps\/status\/\$\{encodeURIComponent\(normalizedAppId\)\}`/)
|
|
435
|
+
assert.match(homeView, /updateHomeShareButtonStatus\(button, appStatus\)/)
|
|
436
|
+
assert.match(homeView, /const requestHomeNetworkSharingStatus = async \(\) =>/)
|
|
437
|
+
assert.match(homeView, /fetch\("\/info\/network-sharing", \{ cache: "no-store" \}\)/)
|
|
438
|
+
assert.match(homeView, /const homeShareTitleHtml = \(label\) =>/)
|
|
439
|
+
assert.match(homeView, /home-app-share-modal__title-icon/)
|
|
440
|
+
assert.match(homeView, /home-app-share-modal__title-meta/)
|
|
441
|
+
assert.match(homeView, /home-app-share-modal__scan-card/)
|
|
442
|
+
assert.match(homeView, /home-app-share-modal__share-card/)
|
|
443
|
+
assert.match(homeView, /Scan to open/)
|
|
444
|
+
assert.match(homeView, /title: homeShareTitleHtml\(title\)/)
|
|
445
|
+
assert.match(homeView, /Install Home Server support/)
|
|
446
|
+
assert.match(homeView, /Turn on Home Server/)
|
|
447
|
+
assert.match(homeView, /Home Server support is installed but turned off/)
|
|
448
|
+
assert.match(homeView, /Open Home Server settings/)
|
|
449
|
+
assert.doesNotMatch(homeView, /Same-Wi-Fi/)
|
|
450
|
+
assert.doesNotMatch(homeView, /Network module/)
|
|
451
|
+
assert.doesNotMatch(homeView, /local routing service/)
|
|
452
|
+
assert.match(homeActionModal, /class='home-mode-command home-share-app'/)
|
|
453
|
+
assert.match(homeActionModal, /data-app-id='<%= homeActionsAppId %>'/)
|
|
454
|
+
assert.match(homeActionModal, />Open on another device</)
|
|
455
|
+
assert.match(homeActionModal, />Home Server</)
|
|
456
|
+
})
|
|
457
|
+
|
|
458
|
+
test("home actions modal renders Home Server app sharing data for running apps", async () => {
|
|
459
|
+
const html = await ejs.renderFile(path.resolve(root, "server/views/partials/home_action_modal.ejs"), {
|
|
460
|
+
id: "home-actions-share-test",
|
|
461
|
+
item: {
|
|
462
|
+
icon: "",
|
|
463
|
+
name: "Test App",
|
|
464
|
+
filepath: "/tmp/pinokio/api/test app.git",
|
|
465
|
+
uri: "test app.git",
|
|
466
|
+
menu: [],
|
|
467
|
+
view_url: "/v/test%20app.git",
|
|
468
|
+
dev_url: "/p/test%20app.git/dev",
|
|
469
|
+
url: "/p/test%20app.git",
|
|
470
|
+
terminal_online_count: 0,
|
|
471
|
+
running: true,
|
|
472
|
+
ready_url: "http://127.0.0.1:42004",
|
|
473
|
+
external_ready_urls: [{ url: "http://192.168.86.229:42111", transport: "ip", scope: "lan" }]
|
|
474
|
+
}
|
|
475
|
+
})
|
|
476
|
+
|
|
477
|
+
const dom = new JSDOM(html)
|
|
478
|
+
const button = dom.window.document.querySelector(".home-share-app")
|
|
479
|
+
assert.ok(button)
|
|
480
|
+
assert.equal(button.getAttribute("data-app-id"), "test app.git")
|
|
481
|
+
assert.equal(button.getAttribute("data-app-name"), "Test App")
|
|
482
|
+
assert.equal(button.getAttribute("data-app-ready-url"), "http://127.0.0.1:42004")
|
|
483
|
+
assert.deepEqual(JSON.parse(button.getAttribute("data-app-external-ready-urls")), [
|
|
484
|
+
{ url: "http://192.168.86.229:42111", transport: "ip", scope: "lan" }
|
|
485
|
+
])
|
|
486
|
+
})
|
|
487
|
+
|
|
488
|
+
test("home app sharing falls back to loopback Web UI menu targets", () => {
|
|
489
|
+
const server = Object.create(Server.prototype)
|
|
490
|
+
server.appRegistry = {
|
|
491
|
+
isLoopbackHostname(hostname) {
|
|
492
|
+
return hostname === "localhost" || hostname === "0.0.0.0" || hostname === "::1" || hostname.startsWith("127.")
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
assert.equal(server.findHomeShareReadyUrlFromMenu([
|
|
497
|
+
{ btn: "Terminal", href: "/api/cropper.git/start.js" },
|
|
498
|
+
{ btn: "Open Web UI", target: "@http://127.0.0.1:42004", href: "http://127.0.0.1:42004" }
|
|
499
|
+
]), "http://127.0.0.1:42004/")
|
|
500
|
+
assert.equal(server.findHomeShareReadyUrlFromMenu([
|
|
501
|
+
{ btn: "Docs", href: "https://example.com" }
|
|
502
|
+
]), "")
|
|
503
|
+
})
|
|
504
|
+
|
|
505
|
+
test("global home server popover exposes machine and app sharing from the navbar", async () => {
|
|
506
|
+
const server = await fs.readFile(path.resolve(root, "server/index.js"), "utf8")
|
|
507
|
+
const popover = await fs.readFile(path.resolve(root, "server/views/partials/home_server_popover.ejs"), "utf8")
|
|
508
|
+
const assets = await fs.readFile(path.resolve(root, "server/views/partials/home_server_popover_assets.ejs"), "utf8")
|
|
509
|
+
const homeView = await fs.readFile(path.resolve(root, "server/views/index.ejs"), "utf8")
|
|
510
|
+
const appView = await fs.readFile(path.resolve(root, "server/views/app.ejs"), "utf8")
|
|
511
|
+
const networkView = await fs.readFile(path.resolve(root, "server/views/network.ejs"), "utf8")
|
|
512
|
+
const netView = await fs.readFile(path.resolve(root, "server/views/net.ejs"), "utf8")
|
|
513
|
+
const sharedNav = await fs.readFile(path.resolve(root, "server/views/partials/app_navheader.ejs"), "utf8")
|
|
514
|
+
const exploreView = await fs.readFile(path.resolve(root, "server/views/explore.ejs"), "utf8")
|
|
515
|
+
const settingsView = await fs.readFile(path.resolve(root, "server/views/settings.ejs"), "utf8")
|
|
516
|
+
const terminalView = await fs.readFile(path.resolve(root, "server/views/terminal.ejs"), "utf8")
|
|
517
|
+
const normalHeaderViews = await Promise.all([
|
|
518
|
+
"create.ejs",
|
|
519
|
+
"keys.ejs",
|
|
520
|
+
"env_editor.ejs",
|
|
521
|
+
"task.ejs",
|
|
522
|
+
"general_editor.ejs",
|
|
523
|
+
"editor.ejs",
|
|
524
|
+
"shell.ejs",
|
|
525
|
+
"pro.ejs"
|
|
526
|
+
].map(async (file) => [file, await fs.readFile(path.resolve(root, "server/views", file), "utf8")]))
|
|
527
|
+
|
|
528
|
+
assert.match(server, /async getNetworkSharingStatus\(\)/)
|
|
529
|
+
assert.match(server, /if \(running\) \{\s*installed = true\s*\}/)
|
|
530
|
+
assert.match(server, /this\.app\.get\("\/info\/home-server"/)
|
|
531
|
+
assert.match(server, /buildHomeServerShellUrl\(peerInfo\)/)
|
|
532
|
+
assert.match(server, /collectHomeServerMachines\(peerInfo\)/)
|
|
533
|
+
assert.match(server, /collectHomeServerApps\(\)/)
|
|
534
|
+
assert.match(server, /collectHomeServerRoutes\(peerInfo, apps, \[shellUrl\]\)/)
|
|
535
|
+
assert.match(server, /status === "on" \? await this\.collectHomeServerApps\(\) : \[\]/)
|
|
536
|
+
assert.match(server, /status === "on" \? this\.collectHomeServerRoutes\(peerInfo, apps, \[shellUrl\]\) : \[\]/)
|
|
537
|
+
assert.match(server, /machines/)
|
|
538
|
+
assert.match(server, /routes/)
|
|
539
|
+
assert.match(popover, /data-home-server-popover/)
|
|
540
|
+
assert.match(popover, /data-home-server-trigger/)
|
|
541
|
+
assert.match(popover, /data-home-server-panel/)
|
|
542
|
+
assert.match(assets, /right: 0;/)
|
|
543
|
+
assert.match(assets, /width: 420px;/)
|
|
544
|
+
assert.match(assets, /max-height: calc\(100vh - 90px\);/)
|
|
545
|
+
assert.match(assets, /data-home-server-open="true"/)
|
|
546
|
+
assert.match(assets, /body\.dark \.home-server-popover__pill \{/)
|
|
547
|
+
assert.match(assets, /body\.dark \.home-server-popover__pill\.is-on/)
|
|
548
|
+
assert.match(assets, /body\.dark \.home-server-popover__switch \{/)
|
|
549
|
+
assert.match(assets, /home-server-popover__switch\[aria-checked="true"\]:disabled/)
|
|
550
|
+
assert.match(assets, /body\.dark \.home-server-popover__footer-note/)
|
|
551
|
+
assert.match(assets, /body\.dark \.home-server-popover__warning \{/)
|
|
552
|
+
assert.match(assets, /body\.dark \.home-server-popover__spinner \{/)
|
|
553
|
+
assert.doesNotMatch(assets, /data-home-server-status="on"] \.home-server-popover__trigger/)
|
|
554
|
+
assert.match(assets, /fetch\("\/info\/home-server", \{ cache: "no-store" \}\)/)
|
|
555
|
+
assert.match(assets, /const shouldPollState = \(data\) =>/)
|
|
556
|
+
assert.match(assets, /return !app\.url \|\| \(state && state !== "ready"\)/)
|
|
557
|
+
assert.match(assets, /refreshPolling\(payload\)/)
|
|
558
|
+
assert.match(assets, /closePanel[\s\S]*stopPolling\(\)/)
|
|
559
|
+
assert.match(assets, /document\.addEventListener\("pointerdown"[\s\S]*true\)/)
|
|
560
|
+
assert.match(assets, /document\.addEventListener\("click"[\s\S]*true\)/)
|
|
561
|
+
assert.match(assets, /const isEmbeddedFrame = \(element\) =>/)
|
|
562
|
+
assert.match(assets, /tagName === "IFRAME" \|\| tagName === "WEBVIEW"/)
|
|
563
|
+
assert.match(assets, /const closeIfFrameFocused = \(\) =>/)
|
|
564
|
+
assert.match(assets, /document\.addEventListener\("focusin"[\s\S]*isEmbeddedFrame\(event\.target\)[\s\S]*true\)/)
|
|
565
|
+
assert.match(assets, /window\.addEventListener\("blur"[\s\S]*closeIfFrameFocused/)
|
|
566
|
+
assert.match(assets, /data-home-server-switch/)
|
|
567
|
+
assert.match(assets, /const switchChecked = status === "on" \|\| status === "starting"/)
|
|
568
|
+
assert.match(assets, /Use this computer as a Home Server/)
|
|
569
|
+
assert.match(assets, /open Pinokio and running app Web UIs from phones, tablets, and other computers/)
|
|
570
|
+
assert.match(assets, /Turning on Home Server/)
|
|
571
|
+
assert.match(assets, /Preparing Pinokio and running app Web UIs for phones, tablets, and other computers/)
|
|
572
|
+
assert.match(assets, /Links will appear here when Home Server is ready/)
|
|
573
|
+
assert.match(assets, /Preparing Home Server link/)
|
|
574
|
+
assert.match(assets, /could not turn on Home Server/)
|
|
575
|
+
assert.doesNotMatch(assets, /Creating local routes/)
|
|
576
|
+
assert.doesNotMatch(assets, /Creating home-network route/)
|
|
577
|
+
assert.doesNotMatch(assets, /local network routes/)
|
|
578
|
+
assert.doesNotMatch(assets, /network router/)
|
|
579
|
+
assert.match(assets, /fetch\("\/network", \{/)
|
|
580
|
+
assert.match(assets, /PINOKIO_NETWORK_ACTIVE: active \? "1" : "0"/)
|
|
581
|
+
assert.match(assets, /PINOKIO_HTTPS_ACTIVE: active \? "1" : "0"/)
|
|
582
|
+
assert.match(assets, /fetch\("\/restart", \{ method: "post" \}\)/)
|
|
583
|
+
assert.match(assets, /Home Server support is not installed/)
|
|
584
|
+
assert.match(assets, /Install Home Server support/)
|
|
585
|
+
assert.match(assets, /Network settings/)
|
|
586
|
+
assert.match(assets, /home-server-popover__footer-row/)
|
|
587
|
+
assert.match(assets, /No running app Web UIs yet/)
|
|
588
|
+
assert.match(assets, /home-server-popover__app-row is-shell[\s\S]{0,300}home-server-popover__app-dot/)
|
|
589
|
+
assert.doesNotMatch(assets, /home-server-popover__app-row is-shell[\s\S]{0,300}fa-solid fa-wifi/)
|
|
590
|
+
assert.match(assets, /Other local services/)
|
|
591
|
+
assert.match(assets, /routesHtml\(data\.routes\)/)
|
|
592
|
+
assert.match(assets, /home-server-popover__app-row is-route[\s\S]{0,220}home-server-popover__app-dot/)
|
|
593
|
+
assert.doesNotMatch(assets, /home-server-popover__app-icon/)
|
|
594
|
+
assert.match(assets, /Available machines/)
|
|
595
|
+
assert.match(assets, /home-server-popover__machine-link/)
|
|
596
|
+
assert.match(assets, /data-home-server-qr/)
|
|
597
|
+
assert.match(assets, /data-home-server-qr-preview/)
|
|
598
|
+
assert.match(assets, /showQrPreview\(/)
|
|
599
|
+
assert.doesNotMatch(assets, /href="\$\{escapeHtml\(qrUrl\)\}"[\s\S]*Show QR code/)
|
|
600
|
+
assert.match(assets, /target="_blank" rel="noreferrer" title="\$\{escapeHtml\(url\)\}"/)
|
|
601
|
+
assert.match(assets, /View routes/)
|
|
602
|
+
assert.match(assets, /Only devices on this local network can open these links\./)
|
|
603
|
+
assert.match(homeView, /partials\/home_server_popover/)
|
|
604
|
+
assert.match(homeView, /partials\/home_server_popover_assets/)
|
|
605
|
+
assert.match(appView, /partials\/home_server_popover/)
|
|
606
|
+
assert.match(appView, /partials\/home_server_popover_assets/)
|
|
607
|
+
assert.match(networkView, /partials\/home_server_popover/)
|
|
608
|
+
assert.match(networkView, /partials\/home_server_popover_assets/)
|
|
609
|
+
assert.match(netView, /partials\/home_server_popover/)
|
|
610
|
+
assert.match(netView, /partials\/home_server_popover_assets/)
|
|
611
|
+
assert.match(sharedNav, /include\('home_server_popover'\)/)
|
|
612
|
+
assert.match(sharedNav, /include\('home_server_popover_assets'\)/)
|
|
613
|
+
assert.match(exploreView, /partials\/home_server_popover/)
|
|
614
|
+
assert.match(exploreView, /partials\/home_server_popover_assets/)
|
|
615
|
+
assert.match(settingsView, /partials\/home_server_popover/)
|
|
616
|
+
assert.match(settingsView, /partials\/home_server_popover_assets/)
|
|
617
|
+
assert.match(terminalView, /partials\/home_server_popover/)
|
|
618
|
+
assert.match(terminalView, /partials\/home_server_popover_assets/)
|
|
619
|
+
for (const [file, source] of normalHeaderViews) {
|
|
620
|
+
assert.match(source, /partials\/home_server_popover/, `${file} includes the Home Server popover`)
|
|
621
|
+
assert.match(source, /partials\/home_server_popover_assets/, `${file} includes the Home Server popover assets`)
|
|
622
|
+
}
|
|
623
|
+
assert.doesNotMatch(appView, /open-app-share-modal/)
|
|
624
|
+
})
|
|
625
|
+
|
|
626
|
+
test("navbar URL picker is hidden without removing URL dropdown behavior", async () => {
|
|
627
|
+
const styles = await fs.readFile(path.resolve(root, "server/public/urldropdown.css"), "utf8")
|
|
628
|
+
const script = await fs.readFile(path.resolve(root, "server/public/urldropdown.js"), "utf8")
|
|
629
|
+
|
|
630
|
+
assert.match(styles, /header\.navheader \.urlbar\s*\{\s*pointer-events: none;\s*visibility: hidden;\s*\}/)
|
|
631
|
+
assert.match(styles, /header\.navheader #mobile-link-button\s*\{\s*display: none !important;\s*\}/)
|
|
632
|
+
assert.match(script, /function initUrlDropdown\(config = \{\}\)/)
|
|
633
|
+
assert.match(script, /ensureFallbackInput/)
|
|
634
|
+
assert.match(script, /fetchApps\(\)/)
|
|
635
|
+
assert.match(script, /fetchProcesses\(\)/)
|
|
636
|
+
assert.match(script, /showMobileModal/)
|
|
637
|
+
})
|
|
638
|
+
|
|
639
|
+
test("home server dropdown exposes router-discovered non-Pinokio routes separately", () => {
|
|
640
|
+
const server = Object.create(Server.prototype)
|
|
641
|
+
const routes = server.collectHomeServerRoutes({
|
|
642
|
+
router_info: [
|
|
643
|
+
{
|
|
644
|
+
name: "node",
|
|
645
|
+
title: "Pinokio",
|
|
646
|
+
port: "42000",
|
|
647
|
+
external_hosts: [{ url: "192.168.86.229:42003", scope: "lan", interface: "en0" }]
|
|
648
|
+
},
|
|
649
|
+
{
|
|
650
|
+
name: "node",
|
|
651
|
+
title: "theDAW",
|
|
652
|
+
port: "5173",
|
|
653
|
+
external_hosts: [{ url: "192.168.86.229:42015", scope: "lan", interface: "en0" }]
|
|
654
|
+
},
|
|
655
|
+
{
|
|
656
|
+
name: "python",
|
|
657
|
+
port: "8600",
|
|
658
|
+
external_hosts: [{ url: "192.168.86.229:42016", scope: "lan", interface: "en0" }]
|
|
659
|
+
},
|
|
660
|
+
{
|
|
661
|
+
name: "chrome-headless-shell",
|
|
662
|
+
port: "58738",
|
|
663
|
+
external_ip: "192.168.86.229:42030"
|
|
664
|
+
}
|
|
665
|
+
]
|
|
666
|
+
}, [{
|
|
667
|
+
name: "theDAW",
|
|
668
|
+
url: "http://192.168.86.229:42015/",
|
|
669
|
+
external_ready_urls: [{ url: "http://192.168.86.229:42015/" }]
|
|
670
|
+
}], ["http://192.168.86.229:42003"])
|
|
671
|
+
|
|
672
|
+
assert.deepEqual(routes, [
|
|
673
|
+
{
|
|
674
|
+
name: "chrome-headless-shell",
|
|
675
|
+
port: "58738",
|
|
676
|
+
url: "http://192.168.86.229:42030",
|
|
677
|
+
urls: [{ url: "http://192.168.86.229:42030", scope: "lan", interface: "" }],
|
|
678
|
+
state: "ready"
|
|
679
|
+
},
|
|
680
|
+
{
|
|
681
|
+
name: "python",
|
|
682
|
+
port: "8600",
|
|
683
|
+
url: "http://192.168.86.229:42016",
|
|
684
|
+
urls: [{ url: "http://192.168.86.229:42016", scope: "lan", interface: "en0" }],
|
|
685
|
+
state: "ready"
|
|
686
|
+
}
|
|
687
|
+
])
|
|
688
|
+
})
|
|
689
|
+
|
|
690
|
+
test("network page merges current machine route inventory without redirecting away", async () => {
|
|
691
|
+
const server = await fs.readFile(path.resolve(root, "server/index.js"), "utf8")
|
|
692
|
+
const networkView = await fs.readFile(path.resolve(root, "server/views/network.ejs"), "utf8")
|
|
693
|
+
|
|
694
|
+
assert.match(server, /res\.render\("network", \{[\s\S]*selected_name: this\.kernel\.peer\.name/)
|
|
695
|
+
assert.match(server, /res\.render\("network", \{[\s\S]*routeCount/)
|
|
696
|
+
assert.match(server, /res\.render\("network", \{[\s\S]*allow_dns_creation/)
|
|
697
|
+
assert.match(networkView, /<h1 class='task-title'>Home Server<\/h1>/)
|
|
698
|
+
assert.match(networkView, /partials\/net_summary/)
|
|
699
|
+
assert.match(networkView, /This machine routes/)
|
|
700
|
+
assert.match(networkView, /partials\/net_route_list/)
|
|
701
|
+
assert.match(networkView, /data-net-routes-endpoint="\/net\/<%= encodeURIComponent\(selected_name\) %>\/routes"/)
|
|
702
|
+
assert.match(networkView, /const netRoutesEndpoint = routeListEl/)
|
|
703
|
+
assert.match(networkView, /fetch\(netRoutesEndpoint, \{ cache: "no-store" \}\)/)
|
|
704
|
+
assert.match(networkView, /class='dns-modal'/)
|
|
705
|
+
assert.match(networkView, /event\.target\.closest\('\.get-dns-btn'\)/)
|
|
706
|
+
assert.doesNotMatch(networkView, /location\.href = "\/net\/" \+ res\.peer_name/)
|
|
707
|
+
assert.match(networkView, /location\.href = "\/network"/)
|
|
708
|
+
})
|
|
709
|
+
|
|
710
|
+
test("home server machine rows use peer shell URLs as primary destinations", () => {
|
|
711
|
+
const server = Object.create(Server.prototype)
|
|
712
|
+
server.port = 42000
|
|
713
|
+
server.kernel = {
|
|
714
|
+
peer: {
|
|
715
|
+
active: true,
|
|
716
|
+
host: "192.168.86.229",
|
|
717
|
+
info: {
|
|
718
|
+
"192.168.86.229": {
|
|
719
|
+
active: true,
|
|
720
|
+
host: "192.168.86.229",
|
|
721
|
+
name: "p229",
|
|
722
|
+
platform: "darwin",
|
|
723
|
+
port_mapping: { "42000": 42003 },
|
|
724
|
+
router_info: []
|
|
725
|
+
},
|
|
726
|
+
"192.168.86.120": {
|
|
727
|
+
active: true,
|
|
728
|
+
host: "192.168.86.120",
|
|
729
|
+
name: "studio",
|
|
730
|
+
platform: "darwin",
|
|
731
|
+
port_mapping: { "42000": 42009 },
|
|
732
|
+
router_info: [{ external_router: ["studio.localhost"] }],
|
|
733
|
+
installed: [{ name: "cropper" }],
|
|
734
|
+
rewrite_mapping: { web: {} }
|
|
735
|
+
},
|
|
736
|
+
"192.168.86.121": {
|
|
737
|
+
active: true,
|
|
738
|
+
host: "192.168.86.121",
|
|
739
|
+
name: "offline-route",
|
|
740
|
+
platform: "linux",
|
|
741
|
+
port_mapping: {},
|
|
742
|
+
router_info: []
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
const rows = server.collectHomeServerMachines({ host: "192.168.86.229" })
|
|
749
|
+
|
|
750
|
+
assert.equal(rows.length, 2)
|
|
751
|
+
assert.deepEqual(rows[0], {
|
|
752
|
+
name: "studio",
|
|
753
|
+
host: "192.168.86.120",
|
|
754
|
+
platform: "darwin",
|
|
755
|
+
url: "http://192.168.86.120:42009",
|
|
756
|
+
available: true,
|
|
757
|
+
current: false,
|
|
758
|
+
route_url: "/net/studio",
|
|
759
|
+
route_count: 3
|
|
760
|
+
})
|
|
761
|
+
assert.equal(rows[1].name, "offline-route")
|
|
762
|
+
assert.equal(rows[1].url, null)
|
|
763
|
+
assert.equal(rows[1].available, false)
|
|
764
|
+
assert.equal(rows[1].route_url, "/net/offline-route")
|
|
765
|
+
|
|
766
|
+
server.port = 43000
|
|
767
|
+
assert.equal(server.buildHomeServerShellUrl({
|
|
768
|
+
host: "192.168.86.229",
|
|
769
|
+
port_mapping: { "42000": 42003 }
|
|
770
|
+
}), "")
|
|
771
|
+
})
|
|
772
|
+
|
|
418
773
|
test("home actions drawer background follows the home page surface", async () => {
|
|
419
774
|
const homeView = await fs.readFile(path.resolve(root, "server/views/index.ejs"), "utf8")
|
|
420
775
|
|
|
@@ -5,27 +5,37 @@ const test = require('node:test')
|
|
|
5
5
|
|
|
6
6
|
const sidebarFile = path.resolve(__dirname, '..', 'server', 'views', 'partials', 'main_sidebar.ejs')
|
|
7
7
|
|
|
8
|
-
test('main sidebar
|
|
8
|
+
test('main sidebar moves Home Server under Configure', async () => {
|
|
9
9
|
const source = await fs.readFile(sidebarFile, 'utf8')
|
|
10
10
|
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
const
|
|
11
|
+
const manageIndex = source.indexOf('aria-label="Manage"')
|
|
12
|
+
const configureIndex = source.indexOf('aria-label="Configure"')
|
|
13
|
+
const homeServerIndex = source.indexOf('Home Server')
|
|
14
|
+
const autolaunchIndex = source.indexOf('Autolaunch')
|
|
14
15
|
|
|
15
|
-
assert.notEqual(
|
|
16
|
-
assert.notEqual(
|
|
17
|
-
assert.notEqual(
|
|
18
|
-
assert.
|
|
19
|
-
assert.ok(
|
|
16
|
+
assert.notEqual(manageIndex, -1)
|
|
17
|
+
assert.notEqual(configureIndex, -1)
|
|
18
|
+
assert.notEqual(homeServerIndex, -1)
|
|
19
|
+
assert.notEqual(autolaunchIndex, -1)
|
|
20
|
+
assert.ok(manageIndex < configureIndex)
|
|
21
|
+
assert.ok(configureIndex < homeServerIndex)
|
|
22
|
+
assert.ok(homeServerIndex < autolaunchIndex)
|
|
23
|
+
assert.match(source, /href="\/network"[\s\S]*Home Server/)
|
|
24
|
+
assert.doesNotMatch(source, /aria-label="Computer"/)
|
|
25
|
+
assert.doesNotMatch(source, />This machine</)
|
|
26
|
+
assert.doesNotMatch(source, />Local network</)
|
|
20
27
|
})
|
|
21
28
|
|
|
22
|
-
test('main sidebar
|
|
29
|
+
test('main sidebar no longer renders peer rows or phone access modal', async () => {
|
|
23
30
|
const source = await fs.readFile(sidebarFile, 'utf8')
|
|
31
|
+
const style = await fs.readFile(path.resolve(__dirname, '..', 'server', 'public', 'style.css'), 'utf8')
|
|
24
32
|
|
|
25
|
-
assert.
|
|
26
|
-
assert.
|
|
27
|
-
assert.
|
|
28
|
-
assert.
|
|
29
|
-
assert.
|
|
30
|
-
assert.
|
|
33
|
+
assert.doesNotMatch(source, /sidebarList\.forEach/)
|
|
34
|
+
assert.doesNotMatch(source, /href="\/net\//)
|
|
35
|
+
assert.doesNotMatch(source, /main-sidebar-phone-trigger/)
|
|
36
|
+
assert.doesNotMatch(source, /data-peer-access-open/)
|
|
37
|
+
assert.doesNotMatch(source, /data-peer-access-modal/)
|
|
38
|
+
assert.doesNotMatch(source, /sidebarPhoneAccessNeedsSetup/)
|
|
39
|
+
assert.doesNotMatch(source, /peer_access_router_installed/)
|
|
40
|
+
assert.doesNotMatch(style, /main-sidebar-peer/)
|
|
31
41
|
})
|