Merge branch 'main' of ssh://git.science.uu.nl/ics/sp/2025/n25b/pepperplus-ui into feat/face-detection
This commit is contained in:
2
.env.example
Normal file
2
.env.example
Normal file
@@ -0,0 +1,2 @@
|
||||
# The location of the backend
|
||||
VITE_API_BASE_URL=http://localhost:8000
|
||||
@@ -28,6 +28,14 @@ npm run dev
|
||||
|
||||
It should automatically reload when you save changes.
|
||||
|
||||
## Environment
|
||||
|
||||
Copy `.env.example` to `.env.local` and adjust values as needed:
|
||||
|
||||
```shell
|
||||
cp .env.example .env.local
|
||||
```
|
||||
|
||||
## Git Hooks
|
||||
|
||||
To activate automatic linting, branch name checks and commit message checks, run:
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
{/*
|
||||
/*
|
||||
This program has been developed by students from the bachelor Computer Science at Utrecht
|
||||
University within the Software Project course.
|
||||
© Copyright Utrecht University (Department of Information and Computing Sciences)
|
||||
*/}
|
||||
*/
|
||||
.logopepper {
|
||||
height: 8em;
|
||||
padding: 1.5em;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
{/*
|
||||
/*
|
||||
This program has been developed by students from the bachelor Computer Science at Utrecht
|
||||
University within the Software Project course.
|
||||
© Copyright Utrecht University (Department of Information and Computing Sciences)
|
||||
*/}
|
||||
*/
|
||||
.filter-root {
|
||||
position: relative;
|
||||
display: flex;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
{/*
|
||||
/*
|
||||
This program has been developed by students from the bachelor Computer Science at Utrecht
|
||||
University within the Software Project course.
|
||||
© Copyright Utrecht University (Department of Information and Computing Sciences)
|
||||
*/}
|
||||
*/
|
||||
.logging-container {
|
||||
box-sizing: border-box;
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import {useCallback, useEffect, useRef, useState} from "react";
|
||||
|
||||
import {applyPriorityPredicates, type PriorityFilterPredicate} from "../../utils/priorityFiltering.ts";
|
||||
import {cell, type Cell} from "../../utils/cellStore.ts";
|
||||
import { API_BASE_URL } from "../../config/api.ts";
|
||||
|
||||
type ExtraLevelName = 'LLM' | 'OBSERVATION' | 'ACTION' | 'CHAT';
|
||||
|
||||
@@ -210,7 +211,7 @@ export function useLogs(filterPredicates: Map<string, LogFilterPredicate>) {
|
||||
// Only create one SSE connection for the lifetime of the hook.
|
||||
if (sseRef.current) return;
|
||||
|
||||
const es = new EventSource("http://localhost:8000/logs/stream");
|
||||
const es = new EventSource(`${API_BASE_URL}/logs/stream`);
|
||||
sseRef.current = es;
|
||||
|
||||
es.onmessage = (event) => {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
{/*
|
||||
/*
|
||||
This program has been developed by students from the bachelor Computer Science at Utrecht
|
||||
University within the Software Project course.
|
||||
© Copyright Utrecht University (Department of Information and Computing Sciences)
|
||||
*/}
|
||||
*/
|
||||
.text-field {
|
||||
border: 1px solid transparent;
|
||||
border-radius: 5pt;
|
||||
|
||||
11
src/config/api.ts
Normal file
11
src/config/api.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
declare const __VITE_API_BASE_URL__: string | undefined;
|
||||
|
||||
const DEFAULT_API_BASE_URL = "http://localhost:8000";
|
||||
|
||||
const rawApiBaseUrl =
|
||||
(typeof __VITE_API_BASE_URL__ !== "undefined" ? __VITE_API_BASE_URL__ : undefined) ??
|
||||
DEFAULT_API_BASE_URL;
|
||||
|
||||
export const API_BASE_URL = rawApiBaseUrl.endsWith("/")
|
||||
? rawApiBaseUrl.slice(0, -1)
|
||||
: rawApiBaseUrl;
|
||||
@@ -1,8 +1,8 @@
|
||||
{/*
|
||||
/*
|
||||
This program has been developed by students from the bachelor Computer Science at Utrecht
|
||||
University within the Software Project course.
|
||||
© Copyright Utrecht University (Department of Information and Computing Sciences)
|
||||
*/}
|
||||
*/
|
||||
|
||||
:root {
|
||||
font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// University within the Software Project course.
|
||||
// © Copyright Utrecht University (Department of Information and Computing Sciences)
|
||||
import { useEffect, useState } from 'react'
|
||||
import { API_BASE_URL } from '../../config/api.ts';
|
||||
|
||||
/**
|
||||
* Displays the current connection status of a robot in real time.
|
||||
@@ -25,7 +26,7 @@ export default function ConnectedRobots() {
|
||||
useEffect(() => {
|
||||
// Open a Server-Sent Events (SSE) connection to receive live ping updates.
|
||||
// We're expecting a stream of data like that looks like this: `data = False` or `data = True`
|
||||
const eventSource = new EventSource("http://localhost:8000/robot/ping_stream");
|
||||
const eventSource = new EventSource(`${API_BASE_URL}/robot/ping_stream`);
|
||||
eventSource.onmessage = (event) => {
|
||||
|
||||
// Expecting messages in JSON format: `true` or `false`
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
{/*
|
||||
/*
|
||||
This program has been developed by students from the bachelor Computer Science at Utrecht
|
||||
University within the Software Project course.
|
||||
© Copyright Utrecht University (Department of Information and Computing Sciences)
|
||||
*/}
|
||||
*/
|
||||
.read_the_docs {
|
||||
color: #888;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
{/*
|
||||
/*
|
||||
This program has been developed by students from the bachelor Computer Science at Utrecht
|
||||
University within the Software Project course.
|
||||
© Copyright Utrecht University (Department of Information and Computing Sciences)
|
||||
*/}
|
||||
*/
|
||||
.dashboardContainer {
|
||||
display: grid;
|
||||
grid-template-columns: 2fr 1fr; /* Left = content, Right = logs */
|
||||
|
||||
@@ -2,16 +2,14 @@
|
||||
// University within the Software Project course.
|
||||
// © Copyright Utrecht University (Department of Information and Computing Sciences)
|
||||
import React, { useEffect } from 'react';
|
||||
|
||||
const API_BASE = "http://localhost:8000";
|
||||
const API_BASE_BP = API_BASE + "/button_pressed"; //UserInterruptAgent endpoint
|
||||
import { API_BASE_URL } from '../../config/api.ts';
|
||||
|
||||
/**
|
||||
* HELPER: Unified sender function
|
||||
*/
|
||||
export const sendAPICall = async (type: string, context: string, endpoint?: string) => {
|
||||
try {
|
||||
const response = await fetch(`${API_BASE_BP}${endpoint ?? ""}`, {
|
||||
const response = await fetch(`${API_BASE_URL}/button_pressed${endpoint ?? ""}`, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ type, context }),
|
||||
@@ -76,7 +74,7 @@ export function useExperimentLogger(onUpdate?: (data: ExperimentStreamData) => v
|
||||
|
||||
useEffect(() => {
|
||||
console.log("Connecting to Experiment Stream...");
|
||||
const eventSource = new EventSource(`${API_BASE}/experiment_stream`);
|
||||
const eventSource = new EventSource(`${API_BASE_URL}/experiment_stream`);
|
||||
|
||||
eventSource.onmessage = (event) => {
|
||||
try {
|
||||
@@ -112,7 +110,7 @@ export function useStatusLogger(onUpdate?: (data: ExperimentStreamData) => void
|
||||
}, [onUpdate]);
|
||||
|
||||
useEffect(() => {
|
||||
const eventSource = new EventSource(`${API_BASE}/status_stream`);
|
||||
const eventSource = new EventSource(`${API_BASE_URL}/status_stream`);
|
||||
eventSource.onmessage = (event) => {
|
||||
try {
|
||||
const parsedData = JSON.parse(event.data);
|
||||
@@ -121,4 +119,4 @@ export function useStatusLogger(onUpdate?: (data: ExperimentStreamData) => void
|
||||
};
|
||||
return () => eventSource.close();
|
||||
}, []);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import styles from './MonitoringPage.module.css';
|
||||
import { sendAPICall } from './MonitoringPageAPI';
|
||||
import { API_BASE_URL } from '../../config/api.ts';
|
||||
|
||||
// --- GESTURE COMPONENT ---
|
||||
export const GestureControls: React.FC = () => {
|
||||
@@ -201,7 +202,7 @@ export const RobotConnected = () => {
|
||||
useEffect(() => {
|
||||
// Open a Server-Sent Events (SSE) connection to receive live ping updates.
|
||||
// We're expecting a stream of data like that looks like this: `data = False` or `data = True`
|
||||
const eventSource = new EventSource("http://localhost:8000/robot/ping_stream");
|
||||
const eventSource = new EventSource(`${API_BASE_URL}/robot/ping_stream`);
|
||||
eventSource.onmessage = (event) => {
|
||||
|
||||
// Expecting messages in JSON format: `true` or `false`
|
||||
@@ -232,4 +233,4 @@ export const RobotConnected = () => {
|
||||
<p className={connected ? styles.connected : styles.disconnected }>{connected ? "● Robot is connected" : "● Robot is disconnected"}</p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
This program has been developed by students from the bachelor Computer Science at Utrecht
|
||||
University within the Software Project course.
|
||||
© Copyright Utrecht University (Department of Information and Computing Sciences)
|
||||
*/
|
||||
.logs {
|
||||
/* grid-area used in MonitoringPage.module.css */
|
||||
grid-area: logs;
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// This program has been developed by students from the bachelor Computer Science at Utrecht
|
||||
// University within the Software Project course.
|
||||
// © Copyright Utrecht University (Department of Information and Computing Sciences)
|
||||
import styles from "./ExperimentLogs.module.css";
|
||||
import {LogMessages} from "../../../components/Logging/Logging.tsx";
|
||||
import {useEffect, useMemo, useState} from "react";
|
||||
@@ -14,6 +17,7 @@ import formatDuration from "../../../utils/formatDuration.ts";
|
||||
import {create} from "zustand";
|
||||
import Dialog from "../../../components/Dialog.tsx";
|
||||
import delayedResolve from "../../../utils/delayedResolve.ts";
|
||||
import { API_BASE_URL } from "../../../config/api.ts";
|
||||
|
||||
/**
|
||||
* Local Zustand store for logging UI preferences.
|
||||
@@ -107,7 +111,7 @@ function DownloadScreen({filenames, refresh}: {filenames: string[] | null, refre
|
||||
|
||||
return <ol className={`${styles.downloadList} margin-0 padding-h-lg scroll-y`}>
|
||||
{filenames!.map((filename) => (
|
||||
<li><a key={filename} href={`http://localhost:8000/api/logs/files/${filename}`} download={filename}>{filename}</a></li>
|
||||
<li><a key={filename} href={`${API_BASE_URL}/api/logs/files/${filename}`} download={filename}>{filename}</a></li>
|
||||
))}
|
||||
</ol>;
|
||||
})();
|
||||
@@ -127,7 +131,7 @@ function DownloadButton() {
|
||||
const [filenames, setFilenames] = useState<string[] | null>(null);
|
||||
|
||||
async function getFiles(): Promise<string[]> {
|
||||
const response = await fetch("http://localhost:8000/api/logs/files");
|
||||
const response = await fetch(`${API_BASE_URL}/api/logs/files`);
|
||||
const files = await response.json();
|
||||
files.sort();
|
||||
return files;
|
||||
@@ -183,4 +187,4 @@ export default function ExperimentLogs() {
|
||||
</div>
|
||||
<LogMessages recordCells={filteredLogs} MessageComponent={ExperimentMessage} />
|
||||
</aside>;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// University within the Software Project course.
|
||||
// © Copyright Utrecht University (Department of Information and Computing Sciences)
|
||||
import { useState, useEffect, useRef } from 'react'
|
||||
import { API_BASE_URL } from '../../config/api.ts';
|
||||
|
||||
/**
|
||||
* Displays a live robot interaction panel with user input, conversation history,
|
||||
@@ -34,7 +35,7 @@ export default function Robot() {
|
||||
*/
|
||||
const sendMessage = async () => {
|
||||
try {
|
||||
const response = await fetch("http://localhost:8000/message", {
|
||||
const response = await fetch(`${API_BASE_URL}/message`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
@@ -60,7 +61,7 @@ export default function Robot() {
|
||||
* The connection resets whenever `conversationIndex` changes.
|
||||
*/
|
||||
useEffect(() => {
|
||||
const eventSource = new EventSource("http://localhost:8000/sse");
|
||||
const eventSource = new EventSource(`${API_BASE_URL}/sse`);
|
||||
|
||||
eventSource.onmessage = (event) => {
|
||||
try {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
{/*
|
||||
/*
|
||||
This program has been developed by students from the bachelor Computer Science at Utrecht
|
||||
University within the Software Project course.
|
||||
© Copyright Utrecht University (Department of Information and Computing Sciences)
|
||||
*/}
|
||||
*/
|
||||
/* editor UI */
|
||||
|
||||
.inner-editor-container {
|
||||
|
||||
@@ -6,6 +6,7 @@ import orderPhaseNodeArray from "../../utils/orderPhaseNodes";
|
||||
import useFlowStore from './visualProgrammingUI/VisProgStores';
|
||||
import { NodeReduces } from './visualProgrammingUI/NodeRegistry';
|
||||
import type { PhaseNode } from "./visualProgrammingUI/nodes/PhaseNode";
|
||||
import { API_BASE_URL } from "../../config/api.ts";
|
||||
|
||||
/**
|
||||
* Reduces the graph into its phases' information and recursively calls their reducing function
|
||||
@@ -28,7 +29,7 @@ export function runProgram() {
|
||||
const program = {phases}
|
||||
console.log(JSON.stringify(program, null, 2));
|
||||
fetch(
|
||||
"http://localhost:8000/program",
|
||||
`${API_BASE_URL}/program`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {"Content-Type": "application/json"},
|
||||
@@ -43,4 +44,4 @@ export function runProgram() {
|
||||
useProgramStore.getState().setProgramState(structuredClone(program));
|
||||
}).catch(() => console.log("Failed to send program to the backend."));
|
||||
console.log(program);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
{/*
|
||||
/*
|
||||
This program has been developed by students from the bachelor Computer Science at Utrecht
|
||||
University within the Software Project course.
|
||||
© Copyright Utrecht University (Department of Information and Computing Sciences)
|
||||
*/}
|
||||
*/
|
||||
.gestureEditor {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
{/*
|
||||
/*
|
||||
This program has been developed by students from the bachelor Computer Science at Utrecht
|
||||
University within the Software Project course.
|
||||
© Copyright Utrecht University (Department of Information and Computing Sciences)
|
||||
*/}
|
||||
*/
|
||||
.planDialog {
|
||||
overflow:visible;
|
||||
width: 80vw;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
{/*
|
||||
/*
|
||||
This program has been developed by students from the bachelor Computer Science at Utrecht
|
||||
University within the Software Project course.
|
||||
© Copyright Utrecht University (Department of Information and Computing Sciences)
|
||||
*/}
|
||||
*/
|
||||
:global(.react-flow__handle.source){
|
||||
border-radius: 100%;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
{/*
|
||||
/*
|
||||
This program has been developed by students from the bachelor Computer Science at Utrecht
|
||||
University within the Software Project course.
|
||||
© Copyright Utrecht University (Department of Information and Computing Sciences)
|
||||
*/}
|
||||
*/
|
||||
.save-load-panel {
|
||||
border-radius: 0 0 5pt 5pt;
|
||||
background-color: canvas;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
{/*
|
||||
/*
|
||||
This program has been developed by students from the bachelor Computer Science at Utrecht
|
||||
University within the Software Project course.
|
||||
© Copyright Utrecht University (Department of Information and Computing Sciences)
|
||||
*/}
|
||||
*/
|
||||
.warnings-sidebar {
|
||||
min-width: auto;
|
||||
max-width: 340px;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
{/*
|
||||
/*
|
||||
This program has been developed by students from the bachelor Computer Science at Utrecht
|
||||
University within the Software Project course.
|
||||
© Copyright Utrecht University (Department of Information and Computing Sciences)
|
||||
*/}
|
||||
*/
|
||||
.operator-switch {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
// This program has been developed by students from the bachelor Computer Science at Utrecht
|
||||
// University within the Software Project course.
|
||||
// © Copyright Utrecht University (Department of Information and Computing Sciences)
|
||||
import { useEffect } from "react";
|
||||
import type { EditorWarning } from "../components/EditorWarnings.tsx";
|
||||
import {
|
||||
type NodeProps,
|
||||
Position,
|
||||
@@ -39,7 +41,7 @@ export type NormNode = Node<NormNodeData>
|
||||
*/
|
||||
export default function NormNode(props: NodeProps<NormNode>) {
|
||||
const data = props.data;
|
||||
const {updateNodeData} = useFlowStore();
|
||||
const {updateNodeData, registerWarning, unregisterWarning} = useFlowStore();
|
||||
|
||||
const text_input_id = `norm_${props.id}_text_input`;
|
||||
const checkbox_id = `goal_${props.id}_checkbox`;
|
||||
@@ -47,10 +49,28 @@ export default function NormNode(props: NodeProps<NormNode>) {
|
||||
const setValue = (value: string) => {
|
||||
updateNodeData(props.id, {norm: value});
|
||||
}
|
||||
//this function is commented out, because of lack of backend implementation.
|
||||
//If you wish to set critical norms, in the UI side, you can uncomment and use this function.
|
||||
|
||||
// const setCritical = (value: boolean) => {
|
||||
// updateNodeData(props.id, {...data, critical: value});
|
||||
// }
|
||||
useEffect(() => {
|
||||
const normText = data.norm || "";
|
||||
|
||||
const startsWithNumberWarning: EditorWarning = {
|
||||
scope: { id: props.id },
|
||||
type: 'ELEMENT_STARTS_WITH_NUMBER',
|
||||
severity: 'ERROR',
|
||||
description: "Norms are not allowed to start with a number."
|
||||
};
|
||||
|
||||
const setCritical = (value: boolean) => {
|
||||
updateNodeData(props.id, {...data, critical: value});
|
||||
}
|
||||
if (/^\d/.test(normText)) {
|
||||
registerWarning(startsWithNumberWarning);
|
||||
} else {
|
||||
unregisterWarning(props.id, 'ELEMENT_STARTS_WITH_NUMBER');
|
||||
}
|
||||
}, [data.norm, props.id, registerWarning, unregisterWarning]);
|
||||
|
||||
return <>
|
||||
<Toolbar nodeId={props.id} allowDelete={true}/>
|
||||
@@ -64,7 +84,10 @@ export default function NormNode(props: NodeProps<NormNode>) {
|
||||
placeholder={"Pepper should ..."}
|
||||
/>
|
||||
</div>
|
||||
<div className={"flex-row gap-md align-center"}>
|
||||
{/*There is no backend implementation yet of how critical norms would
|
||||
be treated differently than normal norms. The commented code below shows
|
||||
how you could add the UI side, if you wish to implement */}
|
||||
{/* <div className={"flex-row gap-md align-center"}>
|
||||
<label htmlFor={checkbox_id}>Critical:</label>
|
||||
<input
|
||||
id={checkbox_id}
|
||||
@@ -72,7 +95,7 @@ export default function NormNode(props: NodeProps<NormNode>) {
|
||||
checked={data.critical || false}
|
||||
onChange={(e) => setCritical(e.target.checked)}
|
||||
/>
|
||||
</div>
|
||||
</div> */}
|
||||
|
||||
|
||||
{data.condition && (<div className={"flex-row gap-md align-center"} data-testid="norm-condition-information">
|
||||
|
||||
11
src/vite-env.d.ts
vendored
Normal file
11
src/vite-env.d.ts
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
/// <reference types="vite/client" />
|
||||
|
||||
interface ImportMetaEnv {
|
||||
readonly VITE_API_BASE_URL?: string;
|
||||
}
|
||||
|
||||
interface ImportMeta {
|
||||
readonly env: ImportMetaEnv;
|
||||
}
|
||||
|
||||
declare const __VITE_API_BASE_URL__: string | undefined;
|
||||
@@ -6,6 +6,7 @@ import "@testing-library/jest-dom";
|
||||
import {type LogRecord, useLogs} from "../../../src/components/Logging/useLogs.ts";
|
||||
import {type cell, useCell} from "../../../src/utils/cellStore.ts";
|
||||
import { StrictMode } from "react";
|
||||
import { API_BASE_URL } from "../../../src/config/api.ts";
|
||||
|
||||
jest.mock("../../../src/utils/priorityFiltering.ts", () => ({
|
||||
applyPriorityPredicates: jest.fn((_log, preds: any[]) =>
|
||||
@@ -83,7 +84,7 @@ describe("useLogs (unit)", () => {
|
||||
);
|
||||
const es = (globalThis as any).__es as MockEventSource;
|
||||
expect(es).toBeTruthy();
|
||||
expect(es.url).toBe("http://localhost:8000/logs/stream");
|
||||
expect(es.url).toBe(`${API_BASE_URL}/logs/stream`);
|
||||
|
||||
unmount();
|
||||
expect(es.close).toHaveBeenCalledTimes(1);
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
useExperimentLogger,
|
||||
useStatusLogger
|
||||
} from '../../../src/pages/MonitoringPage/MonitoringPageAPI';
|
||||
import { API_BASE_URL } from '../../../src/config/api.ts';
|
||||
|
||||
// --- MOCK EVENT SOURCE SETUP ---
|
||||
// This mocks the browser's EventSource so we can manually 'push' messages to our hooks
|
||||
@@ -72,7 +73,7 @@ describe('MonitoringPageAPI', () => {
|
||||
await sendAPICall('test_type', 'test_ctx');
|
||||
|
||||
expect(globalThis.fetch).toHaveBeenCalledWith(
|
||||
'http://localhost:8000/button_pressed',
|
||||
`${API_BASE_URL}/button_pressed`,
|
||||
expect.objectContaining({
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
@@ -220,4 +221,4 @@ describe('MonitoringPageAPI', () => {
|
||||
expect(consoleSpy).toHaveBeenCalledWith('Status stream error:', expect.any(Error));
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
// © Copyright Utrecht University (Department of Information and Computing Sciences)
|
||||
import { render, screen, act, cleanup, fireEvent } from '@testing-library/react';
|
||||
import Robot from '../../../src/pages/Robot/Robot';
|
||||
import { API_BASE_URL } from '../../../src/config/api.ts';
|
||||
|
||||
// Mock EventSource
|
||||
const mockInstances: MockEventSource[] = [];
|
||||
@@ -64,7 +65,7 @@ describe('Robot', () => {
|
||||
await act(async () => fireEvent.click(button));
|
||||
|
||||
expect(globalThis.fetch).toHaveBeenCalledWith(
|
||||
'http://localhost:8000/message',
|
||||
`${API_BASE_URL}/message`,
|
||||
expect.objectContaining({
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
@@ -83,7 +84,7 @@ describe('Robot', () => {
|
||||
);
|
||||
|
||||
expect(globalThis.fetch).toHaveBeenCalledWith(
|
||||
'http://localhost:8000/message',
|
||||
`${API_BASE_URL}/message`,
|
||||
expect.objectContaining({
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
|
||||
@@ -699,15 +699,12 @@ describe('NormNode', () => {
|
||||
/>
|
||||
);
|
||||
|
||||
const checkbox = screen.getByLabelText('Critical:');
|
||||
await user.click(checkbox);
|
||||
|
||||
await waitFor(() => {
|
||||
const state = useFlowStore.getState();
|
||||
expect(state.nodes).toHaveLength(1);
|
||||
expect(state.nodes[0].id).toBe('norm-1');
|
||||
expect(state.nodes[0].data.norm).toBe('');
|
||||
expect(state.nodes[0].data.critical).toBe(true);
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -4,6 +4,9 @@ import react from '@vitejs/plugin-react'
|
||||
// https://vite.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [react()],
|
||||
define: {
|
||||
__VITE_API_BASE_URL__: "import.meta.env.VITE_API_BASE_URL",
|
||||
},
|
||||
css: {
|
||||
modules: {
|
||||
localsConvention: "camelCase",
|
||||
|
||||
Reference in New Issue
Block a user