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
3 changes: 3 additions & 0 deletions fission/bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion fission/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@
"react-dom": "^18.3.1",
"react-icons": "^4.12.0",
"three": "^0.178.0",
"typescript-cookie": "^1.0.6"
"typescript-cookie": "^1.0.6",
"vitest-browser-react": "^1.0.0"
},
"devDependencies": {
"@emotion/react": "^11.14.0",
Expand Down
1 change: 1 addition & 0 deletions fission/src/Window.d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
declare interface Window {
convertAuthToken(code: string): void
gtag: () => void
}
2 changes: 1 addition & 1 deletion fission/src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

:root {
/* font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; */
font-family: "Artifakt";
font-family: Artifakt, sans-serif;
line-height: 1.5;
font-weight: 400;

Expand Down
71 changes: 1 addition & 70 deletions fission/src/main.tsx
Original file line number Diff line number Diff line change
@@ -1,78 +1,9 @@
import ReactDOM from "react-dom/client"
import { ThemeProvider } from "@/ui/ThemeContext"
import { Theme } from "@/ui/helpers/UseThemeHelpers"
import Synthesis from "./Synthesis"
import "./index.css"
import APS from "./aps/APS"

const initialThemeName = "Default"
const defaultColors: Theme = {
InteractiveElementSolid: {
color: { r: 250, g: 162, b: 27, a: 1 },
above: [],
},
InteractiveElementLeft: {
color: { r: 207, g: 114, b: 57, a: 1 },
above: ["Background", "BackgroundSecondary"],
},
InteractiveElementRight: {
color: { r: 212, g: 75, b: 62, a: 1 },
above: ["Background", "BackgroundSecondary"],
},
Background: { color: { r: 0, g: 0, b: 0, a: 1 }, above: [] },
BackgroundSecondary: { color: { r: 18, g: 18, b: 18, a: 1 }, above: [] },
InteractiveBackground: { color: { r: 40, g: 44, b: 47, a: 1 }, above: [] },
MainText: {
color: { r: 255, g: 255, b: 255, a: 1 },
above: [
"Background",
"BackgroundSecondary",
"BackgroundHUD",
"InteractiveBackground",
"InteractiveElementLeft",
"InteractiveElementRight",
],
},
Scrollbar: { color: { r: 170, g: 170, b: 170, a: 1 }, above: [] },
AcceptButton: { color: { r: 33, g: 137, b: 228, a: 1 }, above: [] },
CancelButton: { color: { r: 248, g: 78, b: 78, a: 1 }, above: [] },
InteractiveElementText: {
color: { r: 255, g: 255, b: 255, a: 1 },
above: [],
},
AcceptCancelButtonText: {
color: { r: 0, g: 0, b: 0, a: 1 },
above: ["AcceptButton", "CancelButton"],
},
BackgroundHUD: { color: { r: 23, g: 23, b: 23, a: 1 }, above: [] },
InteractiveHover: { color: { r: 150, g: 150, b: 150, a: 1 }, above: [] },
InteractiveSelect: { color: { r: 100, g: 100, b: 100, a: 1 }, above: [] },
Icon: {
color: { r: 255, g: 255, b: 255, a: 1 },
above: ["Background", "BackgroundSecondary", "InteractiveBackground"],
},
MainHUDIcon: {
color: { r: 255, g: 255, b: 255, a: 1 },
above: ["BackgroundHUD"],
},
MainHUDCloseIcon: {
color: { r: 0, g: 0, b: 0, a: 1 },
above: ["InteractiveElementRight", "#ffffff"],
},
HighlightHover: { color: { r: 89, g: 255, b: 133, a: 1 }, above: [] },
HighlightSelect: { color: { r: 255, g: 89, b: 133, a: 1 }, above: [] },
SkyboxTop: { color: { r: 255, g: 255, b: 255, a: 1 }, above: [] },
SkyboxBottom: { color: { r: 255, g: 255, b: 255, a: 1 }, above: [] },
FloorGrid: { color: { r: 93, g: 93, b: 93, a: 1 }, above: [] },
MatchRedAlliance: { color: { r: 180, g: 20, b: 20, a: 1 }, above: [] },
MatchBlueAlliance: { color: { r: 20, g: 20, b: 180, a: 1 }, above: [] },
ToastInfo: { color: { r: 126, g: 34, b: 206, a: 1 }, above: [] },
ToastWarning: { color: { r: 234, g: 179, b: 8, a: 1 }, above: [] },
ToastError: { color: { r: 239, g: 68, b: 68, a: 1 }, above: [] },
}
const themes = {
Default: defaultColors,
}
import { initialThemeName, themes, defaultColors } from "@/theme.ts"

window.convertAuthToken = code => APS.convertAuthToken(code)

Expand Down
107 changes: 107 additions & 0 deletions fission/src/test/bootstrap/AppMount.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import { afterAll, assert, beforeEach, describe, expect, expectTypeOf, test, vi } from "vitest"
import { server } from "@vitest/browser/context"

import { cleanup, render, RenderResult } from "vitest-browser-react"
import { ReactElement } from "react"
import World from "@/systems/World.ts"

const { readFile } = server.commands

let screen: RenderResult | null
const renderMock = vi.fn((children: ReactElement) => {
screen = render(children)
})
vi.mock("react-dom/client", () => ({
createRoot: vi.fn(() => ({ render: renderMock })),
}))

describe("React Mounting", async () => {
beforeEach(async () => {
document.documentElement.innerHTML = await readFile("index.html")
screen = null
vi.resetAllMocks()
})

afterAll(() => {
cleanup()
vi.resetModules()
})

test("Root element exists", async () => {
expect(document.getElementById("root")).not.toBeNull()
})

test("Static stylesheets load", async () => {
for (let i = 0; i < 50; i++) {
await wait(200)
if (document.styleSheets.length >= 2) {
break
}
}

expect(document.styleSheets.length).toBe(2)
const iterable = document.fonts.values()
let iterator = iterable.next()
let hasArtifaktFont = false
while (!iterator.done) {
if (iterator.value.family.includes("Artifakt")) {
hasArtifaktFont = true
break
}
iterator = iterable.next()
}
expect(hasArtifaktFont).toBeTruthy()
})

// importing main.tsx has side effects that I could not clean up and can only be done once (per file),
// so I am using one test and many annotations. It's possible that there's a better way, but I couldn't
// find it in 4 hours of trying
test(
"App fully mounts through main.tsx",
async ({ annotate, skip }) => {
skip(server.browser == "firefox", "WebGL bug in Github Actions on Firefox")

await import("@/main.tsx")

expect(window.convertAuthToken).toBeDefined()
expectTypeOf(window.convertAuthToken).toBeFunction()
expect(window.gtag).toBeDefined()
expectTypeOf(window.gtag).toBeFunction()
await annotate("expected global functions mount")

Check notice on line 70 in fission/src/test/bootstrap/AppMount.test.tsx

View workflow job for this annotation

GitHub Actions / Playwright Unit Tests

expected global functions mount

// assorted style rules from index.css
const style = window.getComputedStyle(document.body)
expect(style.overflow).toBe("hidden")
expect(style.overscrollBehavior).toBe("none")
expect(style.fontFamily.split(",")[0].trim()).toBe("Artifakt")
await annotate("index.css applied correctly")

Check notice on line 77 in fission/src/test/bootstrap/AppMount.test.tsx

View workflow job for this annotation

GitHub Actions / Playwright Unit Tests

index.css applied correctly

expect(renderMock).toHaveBeenCalledOnce()
assert(screen != null, "Screen was null")

const screenElement = screen.baseElement
expect(screenElement.querySelector("canvas")).toBeInTheDocument()
expect(screen.getByText("Singleplayer")).toBeInTheDocument()
await annotate("DOM successfully updated to include Synthesis components")

Check notice on line 85 in fission/src/test/bootstrap/AppMount.test.tsx

View workflow job for this annotation

GitHub Actions / Playwright Unit Tests

DOM successfully updated to include Synthesis components
const initWorldSpy = vi.spyOn(World, "initWorld")
await screen.getByText("Singleplayer").click()
expect(initWorldSpy).toHaveBeenCalledOnce()
await annotate("Singleplayer Button calls initWorld")

Check notice on line 89 in fission/src/test/bootstrap/AppMount.test.tsx

View workflow job for this annotation

GitHub Actions / Playwright Unit Tests

Singleplayer Button calls initWorld

await wait(50)

await annotate("Initial Scene DOM", { contentType: "text/html", body: document.documentElement.outerHTML })

Check notice on line 93 in fission/src/test/bootstrap/AppMount.test.tsx

View workflow job for this annotation

GitHub Actions / Playwright Unit Tests

Initial Scene DOM

screen.unmount()

await annotate("Screen unmounted gracefully")

Check notice on line 97 in fission/src/test/bootstrap/AppMount.test.tsx

View workflow job for this annotation

GitHub Actions / Playwright Unit Tests

Screen unmounted gracefully
},
{ timeout: 20000 }
)
})

function wait(milliseconds: number) {
return new Promise(resolve => {
setTimeout(resolve, milliseconds)
})
}
70 changes: 70 additions & 0 deletions fission/src/theme.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { Theme } from "@/ui/helpers/UseThemeHelpers.tsx"

export const initialThemeName = "Default"
export const defaultColors: Theme = {
InteractiveElementSolid: {
color: { r: 250, g: 162, b: 27, a: 1 },
above: [],
},
InteractiveElementLeft: {
color: { r: 207, g: 114, b: 57, a: 1 },
above: ["Background", "BackgroundSecondary"],
},
InteractiveElementRight: {
color: { r: 212, g: 75, b: 62, a: 1 },
above: ["Background", "BackgroundSecondary"],
},
Background: { color: { r: 0, g: 0, b: 0, a: 1 }, above: [] },
BackgroundSecondary: { color: { r: 18, g: 18, b: 18, a: 1 }, above: [] },
InteractiveBackground: { color: { r: 40, g: 44, b: 47, a: 1 }, above: [] },
MainText: {
color: { r: 255, g: 255, b: 255, a: 1 },
above: [
"Background",
"BackgroundSecondary",
"BackgroundHUD",
"InteractiveBackground",
"InteractiveElementLeft",
"InteractiveElementRight",
],
},
Scrollbar: { color: { r: 170, g: 170, b: 170, a: 1 }, above: [] },
AcceptButton: { color: { r: 33, g: 137, b: 228, a: 1 }, above: [] },
CancelButton: { color: { r: 248, g: 78, b: 78, a: 1 }, above: [] },
InteractiveElementText: {
color: { r: 255, g: 255, b: 255, a: 1 },
above: [],
},
AcceptCancelButtonText: {
color: { r: 0, g: 0, b: 0, a: 1 },
above: ["AcceptButton", "CancelButton"],
},
BackgroundHUD: { color: { r: 23, g: 23, b: 23, a: 1 }, above: [] },
InteractiveHover: { color: { r: 150, g: 150, b: 150, a: 1 }, above: [] },
InteractiveSelect: { color: { r: 100, g: 100, b: 100, a: 1 }, above: [] },
Icon: {
color: { r: 255, g: 255, b: 255, a: 1 },
above: ["Background", "BackgroundSecondary", "InteractiveBackground"],
},
MainHUDIcon: {
color: { r: 255, g: 255, b: 255, a: 1 },
above: ["BackgroundHUD"],
},
MainHUDCloseIcon: {
color: { r: 0, g: 0, b: 0, a: 1 },
above: ["InteractiveElementRight", "#ffffff"],
},
HighlightHover: { color: { r: 89, g: 255, b: 133, a: 1 }, above: [] },
HighlightSelect: { color: { r: 255, g: 89, b: 133, a: 1 }, above: [] },
SkyboxTop: { color: { r: 255, g: 255, b: 255, a: 1 }, above: [] },
SkyboxBottom: { color: { r: 255, g: 255, b: 255, a: 1 }, above: [] },
FloorGrid: { color: { r: 93, g: 93, b: 93, a: 1 }, above: [] },
MatchRedAlliance: { color: { r: 180, g: 20, b: 20, a: 1 }, above: [] },
MatchBlueAlliance: { color: { r: 20, g: 20, b: 180, a: 1 }, above: [] },
ToastInfo: { color: { r: 126, g: 34, b: 206, a: 1 }, above: [] },
ToastWarning: { color: { r: 234, g: 179, b: 8, a: 1 }, above: [] },
ToastError: { color: { r: 239, g: 68, b: 68, a: 1 }, above: [] },
}
export const themes = {
[initialThemeName]: defaultColors,
}
Loading