Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { buildSameComputerLoopbackUrl } from "@/lib/secure-context"
import { OCTOBOT_CONNECT_GUIDE_TWO_INTERFACES_URL } from "@/lib/external-links"
import {
INSECURE_CONTEXT_OPTION_LOCAL_SUBLABEL,
INSECURE_CONTEXT_OPTION_LOCAL_TITLE,
INSECURE_CONTEXT_OPTION_REMOTE_TITLE,
INSECURE_CONTEXT_REMOTE_LEAD,
INSECURE_CONTEXT_SAME_COMPUTER_LEAD,
INSECURE_CONTEXT_TWO_INTERFACES_GUIDE_BEFORE,
INSECURE_CONTEXT_TWO_INTERFACES_GUIDE_LINK,
INSECURE_CONTEXT_WHY_ADDRESS_AFTER,
INSECURE_CONTEXT_WHY_ADDRESS_BEFORE,
INSECURE_CONTEXT_WHY_LEAD,
Expand All @@ -31,11 +34,25 @@ export function InsecureContextGuidance({
<div className="space-y-2">
<p>{INSECURE_CONTEXT_WHY_LEAD}</p>
{pageHref !== "" ? (
<p>
{INSECURE_CONTEXT_WHY_ADDRESS_BEFORE}
<span className="break-all font-mono text-foreground">{pageHref}</span>
{INSECURE_CONTEXT_WHY_ADDRESS_AFTER}
</p>
<>
<p>
{INSECURE_CONTEXT_WHY_ADDRESS_BEFORE}
<span className="break-all font-mono text-foreground">{pageHref}</span>
{INSECURE_CONTEXT_WHY_ADDRESS_AFTER}
</p>
<p>
{INSECURE_CONTEXT_TWO_INTERFACES_GUIDE_BEFORE}
<a
href={OCTOBOT_CONNECT_GUIDE_TWO_INTERFACES_URL}
target="_blank"
rel="noopener noreferrer"
className="underline underline-offset-2 text-foreground"
>
{INSECURE_CONTEXT_TWO_INTERFACES_GUIDE_LINK}
</a>
.
</p>
</>
) : null}
</div>
<div className="space-y-3 rounded-md border border-border bg-muted/20 p-4">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
TAILSCALE_ADMIN_CONSOLE_MACHINES_URL,
TAILSCALE_FULL_DOMAIN_EXAMPLE,
TAILSCALE_MAGICDNS_REACHABILITY_LEAD,
TAILSCALE_PRIVATE_NETWORK_CONNECT_GUIDE_LABEL,
TAILSCALE_REMOTE_ACCESS_DIALOG_TITLE,
TAILSCALE_SERVE_NOT_ENABLED_ON_TAILNET_MESSAGE,
TAILSCALE_SERVE_STARTED_RUNNING_MESSAGE,
Expand Down Expand Up @@ -128,7 +129,7 @@ export function TailscaleRemoteAccessDialog({
target="_blank"
rel="noopener noreferrer"
>
Read the full Tailscale guide
{TAILSCALE_PRIVATE_NETWORK_CONNECT_GUIDE_LABEL}
</a>
</Button>
<DialogClose asChild>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
MAGIC_DNS_OPEN_IN_BROWSER_LABEL,
TAILSCALE_ADMIN_CONSOLE_MACHINES_URL,
TAILSCALE_MAGICDNS_REACHABILITY_LEAD,
TAILSCALE_PRIVATE_NETWORK_CONNECT_GUIDE_LABEL,
TAILSCALE_SERVE_NOT_ENABLED_ON_TAILNET_MESSAGE,
TAILSCALE_SERVE_STARTED_RUNNING_MESSAGE,
} from "@/lib/ui-recovery-constants"
Expand Down Expand Up @@ -59,6 +60,7 @@ describe("TailscaleRemoteAccessDialog", () => {
expect(markup).not.toContain('aria-label="Copy command"')
expect(markup).not.toContain('aria-label="Copy URL"')
expect(markup).toContain(OCTOBOT_TAILSCALE_CONNECT_GUIDE_URL)
expect(markup).toContain(TAILSCALE_PRIVATE_NETWORK_CONNECT_GUIDE_LABEL)
vi.unstubAllGlobals()
})
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
confirmAndResetLocalBrowserData,
RecoveryScreen,
} from "@/components/Common/RecoveryScreen"
import { OCTOBOT_CONNECT_GUIDE_TWO_INTERFACES_URL } from "@/lib/external-links"

const mocks = vi.hoisted(() => ({
resetClientStorage: vi.fn().mockResolvedValue(undefined),
Expand Down Expand Up @@ -54,9 +55,16 @@ describe("RecoveryScreen", () => {
})

it("insecure_context omits reset and reload, shows Tailscale setup", () => {
vi.stubGlobal("window", {
location: {
href: "http://192.168.1.50:8000/app/setup?x=1",
port: "8000",
},
})
const markup = renderToStaticMarkup(
<RecoveryScreen failureKind="insecure_context" />,
)
vi.unstubAllGlobals()
expect(markup).not.toContain("Reset local browser data")
expect(markup).not.toContain("Reload page")
expect(markup).toContain("Secure context required")
Expand All @@ -71,6 +79,8 @@ describe("RecoveryScreen", () => {
expect(markup).toContain("share-feedback-stub")
expect(markup).toContain('data-testid="insecure-context-option-remote"')
expect(markup).toContain('data-testid="recovery-insecure-share-feedback"')
expect(markup).toContain(OCTOBOT_CONNECT_GUIDE_TWO_INTERFACES_URL)
expect(markup).toContain("Learn more about the OctoBot interface in ")
expect(markup.toLowerCase()).not.toContain("saved data")
expect(markup.toLowerCase()).not.toContain("local data is fine")
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ import {
} from "@/components/ui/card"
import { buildPairingQrValue } from "@/lib/pairing"
import {
OCTOBOT_BETA_GETTING_STARTED_GUIDE_URL,
OCTOBOT_CONNECT_GUIDE_COMMON_ISSUES_URL,
OCTOBOT_CONNECT_GUIDE_URL,
OCTOBOT_PLAY_STORE_URL,
OCTOBOT_TESTFLIGHT_URL,
OCTOBOT_WEB_INTERFACE_URL,
Expand Down Expand Up @@ -143,16 +144,28 @@ export function ConnectNodeGuide() {
<p className="pt-2 text-center text-sm text-muted-foreground">
Having trouble connecting to your node?{" "}
Try using <strong>Brave</strong> or <strong>Google Chrome</strong> instead of <strong>Firefox</strong> or <strong>Safari</strong>, which are known to sometimes block the
connection to the node. More troubleshooting tips on{" "}
connection to the node.
</p>
<p className="text-center text-sm text-muted-foreground">
See our{" "}
<a
href={OCTOBOT_CONNECT_GUIDE_URL}
target="_blank"
rel="noopener noreferrer"
className="underline underline-offset-4 hover:text-foreground"
>
full connect guide
</a>{" "}
and{" "}
<a
href={OCTOBOT_BETA_GETTING_STARTED_GUIDE_URL}
href={OCTOBOT_CONNECT_GUIDE_COMMON_ISSUES_URL}
target="_blank"
rel="noopener"
rel="noopener noreferrer"
className="underline underline-offset-4 hover:text-foreground"
>
our full guide
</a>
.
common issues
</a>{" "}
if the web app shows Unreachable node or Queued actions.
</p>
</CardContent>
</Card>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { NodeConnectAddressTabs } from "@/components/Setup/NodeConnectAddressTabs"
import { Button } from "@/components/ui/button"
import {
OCTOBOT_CONNECT_GUIDE_COMMON_ISSUES_URL,
OCTOBOT_CONNECT_GUIDE_URL,
} from "@/lib/external-links"

type ManualNodeConnectPanelProps = {
onSwitchToWeb: () => void
Expand All @@ -12,9 +16,27 @@ export function ManualNodeConnectPanel({ onSwitchToWeb }: ManualNodeConnectPanel

<div className="flex flex-col items-center gap-3 pt-2 text-center text-sm text-muted-foreground">
<p>
Having troubles connecting to your node from the app? Start with the web
version
Having troubles connecting to your node from the app? See our{" "}
<a
href={OCTOBOT_CONNECT_GUIDE_URL}
target="_blank"
rel="noopener noreferrer"
className="underline underline-offset-4 hover:text-foreground"
>
full connect guide
</a>{" "}
or{" "}
<a
href={OCTOBOT_CONNECT_GUIDE_COMMON_ISSUES_URL}
target="_blank"
rel="noopener noreferrer"
className="underline underline-offset-4 hover:text-foreground"
>
common issues
</a>
.
</p>
<p>You can also start with the web version.</p>
<Button type="button" variant="outline" onClick={onSwitchToWeb}>
Switch to web
</Button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,14 @@ export function NodeConnectAddressTabs({ audience }: NodeConnectAddressTabsProps

const vpnHostnameHelperText = couldNotDetectVpn ? (
<>
Tailscale may not be running or is disconnected.{" "}
Try restarting Tailscale on the node machine or{" "}
<button
type="button"
className="underline"
onClick={() => setConnectAddressMethod("local")}
>
Use local network instead
</button>
use local network instead
</button>. Note: if you are using another VPN, this might not detect your IP address, you will need to find your it manually.
</>
) : undefined

Expand Down Expand Up @@ -105,13 +105,13 @@ export function NodeConnectAddressTabs({ audience }: NodeConnectAddressTabsProps
rel="noopener noreferrer"
>
<Button type="button" variant="outline">
Read the Tailscale guide
Read the Private Network guide
</Button>
</a>
</div>
<SetupNodeAddressPanel
hostname={vpnHostname}
hostnameLabel="Tailscale IP address or MagicDNS"
hostnameLabel="Private Network IP address or MagicDNS"
hostnameHelperText={vpnHostnameHelperText}
hostnameLoading={isVpnPending || isVpnFetching}
onHostnameRefresh={() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ import {
DialogTitle,
} from "@/components/ui/dialog"
import { Button } from "@/components/ui/button"
import { OCTOBOT_WEB_INTERFACE_URL } from "@/lib/external-links"
import {
OCTOBOT_CONNECT_GUIDE_URL,
OCTOBOT_WEB_INTERFACE_URL,
} from "@/lib/external-links"

type StartAutomationDialogProps = {
open: boolean
Expand Down Expand Up @@ -70,9 +73,17 @@ export function StartAutomationDialog({
to="/settings/connect"
className="underline underline-offset-4 hover:text-foreground"
>
step-by-step guide
</Link>
.
quick step-by-step guide
</Link>{" "}
or the{" "}
<a
href={OCTOBOT_CONNECT_GUIDE_URL}
target="_blank"
rel="noopener noreferrer"
className="underline underline-offset-4 hover:text-foreground"
>
detailed guide on octobot.cloud
</a>{" "} if you have questions.
</p>
<div className="flex flex-wrap justify-center gap-2">
<Button
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { describe, expect, it } from "vitest"

import {
OCTOBOT_CONNECT_GUIDE_COMMON_ISSUES_URL,
OCTOBOT_CONNECT_GUIDE_SAME_COMPUTER_WEB_URL,
OCTOBOT_CONNECT_GUIDE_TWO_INTERFACES_URL,
OCTOBOT_CONNECT_GUIDE_URL,
OCTOBOT_TAILSCALE_CONNECT_GUIDE_URL,
} from "../external-links"

describe("external-links connect guide anchors", () => {
it("uses expected node-connect-guide paths and hashes", () => {
expect(OCTOBOT_CONNECT_GUIDE_URL).toBe(
"https://www.octobot.cloud/en/guides/octobot-installation/node-connect-guide",
)
expect(OCTOBOT_CONNECT_GUIDE_SAME_COMPUTER_WEB_URL).toBe(
`${OCTOBOT_CONNECT_GUIDE_URL}#local-network`,
)
expect(OCTOBOT_TAILSCALE_CONNECT_GUIDE_URL).toBe(
`${OCTOBOT_CONNECT_GUIDE_URL}#private-network`,
)
expect(OCTOBOT_CONNECT_GUIDE_COMMON_ISSUES_URL).toBe(
`${OCTOBOT_CONNECT_GUIDE_URL}#common-issues`,
)
expect(OCTOBOT_CONNECT_GUIDE_TWO_INTERFACES_URL).toBe(
`${OCTOBOT_CONNECT_GUIDE_URL}#the-two-interfaces-you-will-use`,
)
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,25 @@ export const OCTOBOT_TESTFLIGHT_URL = "https://testflight.apple.com/join/Gcb46fF

export const OCTOBOT_WEBSITE_URL = "https://www.octobot.cloud"

export const OCTOBOT_GETTING_STARTED_GUIDE_URL =
`${OCTOBOT_WEBSITE_URL}/en/guides/octobot-getting-started`

/** @deprecated Use OCTOBOT_GETTING_STARTED_GUIDE_URL */
export const OCTOBOT_BETA_GETTING_STARTED_GUIDE_URL =
`${OCTOBOT_WEBSITE_URL}/en/guides/octobot-beta-getting-started`
OCTOBOT_GETTING_STARTED_GUIDE_URL

export const OCTOBOT_CONNECT_GUIDE_URL =
`${OCTOBOT_WEBSITE_URL}/en/guides/octobot-installation/node-connect-guide`

export const OCTOBOT_CONNECT_GUIDE_SAME_COMPUTER_WEB_URL =
`${OCTOBOT_CONNECT_GUIDE_URL}#local-network`

/** Connect guide: Private network (VPN / Tailscale) section */
export const OCTOBOT_TAILSCALE_CONNECT_GUIDE_URL =
`${OCTOBOT_BETA_GETTING_STARTED_GUIDE_URL}#connect-from-anywhere-with-tailscale`
`${OCTOBOT_CONNECT_GUIDE_URL}#private-network`

export const OCTOBOT_CONNECT_GUIDE_COMMON_ISSUES_URL =
`${OCTOBOT_CONNECT_GUIDE_URL}#common-issues`

export const OCTOBOT_CONNECT_GUIDE_TWO_INTERFACES_URL =
`${OCTOBOT_CONNECT_GUIDE_URL}#the-two-interfaces-you-will-use`
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,14 @@ export const TAILSCALE_REMOTE_ACCESS_BUTTON_LABEL = "Set up remote access"

export const TAILSCALE_REMOTE_ACCESS_DIALOG_TITLE = "Remote access with Tailscale"

export const TAILSCALE_PRIVATE_NETWORK_CONNECT_GUIDE_LABEL =
"Private network connect guide"

export const INSECURE_CONTEXT_TWO_INTERFACES_GUIDE_BEFORE =
"Learn more about the OctoBot interface in "

export const INSECURE_CONTEXT_TWO_INTERFACES_GUIDE_LINK = "the guide"

export const TAILSCALE_ADMIN_CONSOLE_MACHINES_URL =
"https://console.tailscale.com/admin/machines"

Expand Down
Loading