Skip to content

Commit 9f7bea4

Browse files
authored
Merge pull request #956 from revisit-studies/dev
v2.4.0
2 parents 8d01a3c + 5aecc62 commit 9f7bea4

329 files changed

Lines changed: 27788 additions & 11982 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.dockerignore

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
.git
2+
.github
3+
node_modules
4+
dist
5+
docs
6+
docsLibraries
7+
playwright-report
8+
test-results
9+
verbose
10+
supabase
11+
tests
12+
.vscode
13+
.husky
14+
.DS_Store
15+
*.log
16+
.claude
17+
.idea
18+
/playwright/.cache/
19+
coverage
20+
*.tsbuildinfo
21+
*.local
22+
.env.local
23+
.env.*.local
24+
public/__revisit-widget
25+
src/public/__revisit-widget

.env

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,6 @@ VITE_REPO_URL="https://github.com/revisit-studies/study/tree/main/public/" # Set
1515

1616
VITE_SUPABASE_URL="https://supabase.revisit.dev"
1717
VITE_SUPABASE_ANON_KEY="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiYW5vbiIsImlzcyI6InN1cGFiYXNlIiwiaWF0IjoxNzYwNjgwODAwLCJleHAiOjE5MTg0NDcyMDB9.IohiSvWUtjylJgn4gMrK3aYfnbz-hUmyb3h87DrQvTc"
18+
19+
VITE_OPENAI_API_URL="https://apps.vdl.sci.utah.edu/openai-proxy" # Your proxy URL for OpenAI API requests
20+

.github/workflows/playwright.yml

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,37 +11,45 @@ jobs:
1111
name: 🧪 ${{ matrix.project }} E2E Tests
1212
runs-on: ${{ matrix.os }}
1313
timeout-minutes: 20
14+
env:
15+
PLAYWRIGHT_BROWSERS_PATH: ${{ matrix.cache_dir }}
16+
PW_CI_REPORTER: dot
17+
PW_CI_WORKERS: ${{ matrix.workers }}
1418
strategy:
1519
fail-fast: false
1620
matrix:
1721
include:
1822
- project: chromium
1923
os: ubuntu-latest
20-
cache_dir: ~/.cache/ms-playwright
24+
cache_dir: /home/runner/.cache/ms-playwright
25+
workers: 3
2126

22-
- project: firefox
23-
os: ubuntu-latest
24-
cache_dir: ~/.cache/ms-playwright
27+
# - project: firefox
28+
# os: ubuntu-latest
29+
# cache_dir: ~/.cache/ms-playwright
2530

2631
- project: webkit
2732
os: macos-14
28-
cache_dir: ~/Library/Caches/ms-playwright
33+
cache_dir: /Users/runner/Library/Caches/ms-playwright
34+
workers: 2
2935
steps:
30-
- uses: actions/checkout@v3
36+
- uses: actions/checkout@v4
3137

32-
- uses: actions/setup-node@v3
38+
- uses: actions/setup-node@v4
3339
with:
3440
node-version: lts/*
3541
cache: "yarn"
3642

3743
- name: Install dependencies
44+
env:
45+
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1
3846
run: yarn install --immutable
3947

4048
- name: Write out playwright version
4149
run: yarn --silent playwright --version > .playwright-version
4250

4351
- name: ⚡️ Cache playwright binaries
44-
uses: actions/cache@v3
52+
uses: actions/cache@v4
4553
id: playwright-cache
4654
with:
4755
path: ${{ matrix.cache_dir }}
@@ -53,10 +61,3 @@ jobs:
5361

5462
- name: Run Playwright tests
5563
run: yarn test --project=${{ matrix.project }}
56-
57-
- name: Upload test results
58-
if: failure()
59-
uses: actions/upload-artifact@v4
60-
with:
61-
name: playwright-report
62-
path: playwright-report

.github/workflows/vitest.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Playwright Tests
1+
name: Unit Tests
22

33
on:
44
pull_request:
@@ -22,5 +22,5 @@ jobs:
2222
- name: Install dependencies
2323
run: yarn install --immutable
2424

25-
- name: Run Playwright tests
25+
- name: Run unit tests
2626
run: yarn unittest

claude.md renamed to AGENTS.md

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ Tech Stack
44
- TypeScript
55
- Vite
66
- Mantine UI
7-
- Firebase/Supabase both with storage and database
7+
- Firebase or Supabase as storage and database backends (.env selects the engine)
88
- Redux for state management with our in-house library Trrack.js for provenance tracking
9-
- Specific Lodash functions (debounce, throttle, isEqual, merge)
9+
- Lodash usage is restricted to: debounce, throttle, isEqual, merge
1010
- React Router for routing
1111
- Eslint and airbnb style guide for code quality
1212

@@ -22,10 +22,10 @@ Verbiage
2222
- "Study Config": The configuration file that defines the parameters and settings of a user study.
2323

2424
Study Configs
25-
The study configurations are defined in JSON files with schemas. These configs specify various aspects of the study, including the visualization tools to be used, the tasks participants need to complete, and the data sources involved. You can find the full definition of the study config schema in the typescript file at src/parser/types.ts. The answers and participant data specifications are stored separately from the study config to allow for flexibility in data collection and analysis, at src/store/types.ts.
25+
The study configurations are defined in JSON files with schemas. These configs specify various aspects of the study, including the visualization tools to be used, the tasks participants need to complete, and the data sources involved. You can find the full definition of the study config schema in the typescript file at src/parser/types.ts. The answers and participant data specifications are stored separately from the study config to allow for flexibility in data collection and analysis, at src/store/types.ts. Study config JSON files live in the public folder under the /public/{studyName}/config.json path.
2626

2727
Imported Libraries
28-
We provide several libraries to facilitate the development of user studies, such as vlat, mini-vlat, nasa-tlx, color-blindness, and more. These libraries are components and sequences that are defined in public/libraries/. Each library has its own folder containing the necessary code and assets. You can import these libraries into your study configs to enhance the functionality and user experience of your studies by adding the libraries to the top level `importedLibraries` field in the study config, and then referencing the components in the `baseComponent` field or in sequences and the sequences in the `sequences` field. When referencing the components and sequences use the following syntax `"$libraryName.components.componentName"` and `"$libraryName.sequences.sequenceName"` respectively.
28+
We provide several libraries to facilitate the development of user studies, such as vlat, mini-vlat, nasa-tlx, color-blindness, and more. These libraries are components and sequences that are defined in public/libraries/. Each library has its own folder containing the necessary code and assets. Use only libraries that exist under public/libraries/ (no ad-hoc local component imports in study configs). You can import these libraries into your study configs to enhance the functionality and user experience of your studies by adding the libraries to the top level `importedLibraries` field in the study config, and then referencing the components in the `baseComponent` field or in sequences and the sequences in the `sequences` field. When referencing the components and sequences use the following syntax `"$libraryName.components.componentName"` and `"$libraryName.sequences.sequenceName"` respectively.
2929

3030
Storage Engines
3131
ReVISit supports multiple storage backends for storing study data, including Firebase and Supabase. This allows researchers to choose the backend that best fits their needs in terms of scalability, ease of use, and integration with other tools. The storage engines are abstracted in the codebase, allowing for easy addition of new storage solutions in the future. The storage engine implementations can be found in src/storage/ directory.
@@ -34,4 +34,14 @@ How you should interact with the codebase
3434
When working with the ReVISit codebase, work only with the source code files available to you. If you need an external library, please ask for approval first (and include how well used the library is). Make sure to follow best practices for React and TypeScript development, including proper state management, component structuring, and code documentation. Pay extra attention to lifecycle methods and hooks to ensure optimal performance and avoid memory leaks, including any updates to existing code. If you encounter any issues or have suggestions for improvements, feel free to bring them up for discussion. Don't interact with git and GitHub directly; instead, focus on the code itself. I'll handle version control and repository management. Always check package.json for the scripts available to you for building, testing, and running the project.
3535

3636
Testing
37-
When adding a new feature or modifying code try to maximize unit test coverage. Unit tests should be colocated with the files they are testing, have the same names as the file with .spec., and use the vitest framework. Apply this to both UI/react code as well as non-UI code. For UI code, we use playwright for end-to-end testing. Try to add e2e tests for any new features that involve user interaction. E2E tests are located in the tests/ directory at the root of the project. Don't run `yarn test` directly; instead, describe the tests you want to run, and I'll handle executing them. You can run unittests locally using `yarn unittest`.
37+
When adding a new feature or modifying code try to maximize unit test coverage. Unit tests should be colocated with the files they are testing, have the same names as the file with .spec., and use the vitest framework. Apply this to both UI/react code as well as non-UI code. For UI code, we use playwright for end-to-end testing. Try to add e2e tests for any new features that involve user interaction. E2E tests are located in the tests/ directory at the root of the project. Don't run `yarn test` directly; instead, describe the tests you want to run, and I'll handle executing them. You can run unittests locally using `yarn unittest`. Preferred commands are those listed in package.json (e.g., `yarn unittest`, `yarn lint`, `yarn typecheck`, `yarn serve`, `yarn build`).
38+
39+
Parser
40+
When adding new features, sometimes it's required to update the parser and the associated types. The parser is located in src/parser/. The parser is responsible for validating and transforming the study config JSON files into a format that the application can use. When updating the parser, ensure that you also update the corresponding types in src/parser/types.ts to reflect any changes made to the study config schema. Make sure to add unit tests for any new parser functionality to ensure its correctness. Additionally, changes to the parser types will require updates to the generated JSON schema files located in src/schemas/. You can regenerate these schema files by running `yarn generate-schemas`.
41+
42+
Sequence
43+
The sequence logic is a crucial part of the ReVISit platform, as it defines the flow of tasks and interactions for participants in a study. A participant's sequence is essentially flattened into a list and navigated through by index. The only exception to this is the dynamic blocks, which function as a nested sequence. The nested sequence has its own index and can be navigated through independently of the main sequence.
44+
45+
DO NOT
46+
- DO NOT add import('...') statements inside src code and test logic. Import at the top of the file only, even for types.
47+
- DO NOT add new libraries without approval.

Dockerfile

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
FROM node:lts AS builder
2+
3+
WORKDIR /app
4+
5+
COPY package.json yarn.lock ./
6+
RUN yarn install --frozen-lockfile
7+
8+
COPY . .
9+
10+
RUN yarn build
11+
12+
RUN node -e "const fs=require('node:fs');const key='VITE_BASE_PATH=';const lines=fs.readFileSync('.env','utf8').split(/\\r?\\n/);let v='';for(const line of lines){if(line.startsWith(key)) v=line.slice(key.length);}v=v.trim();if((v.startsWith('\"')&&v.endsWith('\"'))||(v.startsWith(\"'\")&&v.endsWith(\"'\"))){v=v.slice(1,-1);}if(!v){throw new Error('VITE_BASE_PATH must be defined in .env');}fs.writeFileSync('/tmp/base_path',v);"
13+
14+
FROM nginx:stable AS runtime
15+
16+
COPY --from=builder /app/dist /tmp/dist
17+
COPY --from=builder /tmp/base_path /tmp/base_path
18+
COPY nginx-docker.conf /tmp/nginx-docker.conf
19+
20+
RUN set -eux; \
21+
BASE_PATH="$(cat /tmp/base_path)"; \
22+
rm -rf /usr/share/nginx/html/*; \
23+
if [ "$BASE_PATH" = "/" ]; then \
24+
LOCATION_PATH="/"; \
25+
INDEX_FALLBACK="/index.html"; \
26+
ROOT_REDIRECT_DIRECTIVE="try_files /index.html =404;"; \
27+
cp -R /tmp/dist/. /usr/share/nginx/html/; \
28+
else \
29+
LOCATION_PATH="$BASE_PATH"; \
30+
INDEX_FALLBACK="${BASE_PATH}index.html"; \
31+
ROOT_REDIRECT_DIRECTIVE="return 302 ${BASE_PATH};"; \
32+
TARGET_DIR="/usr/share/nginx/html${BASE_PATH}"; \
33+
mkdir -p "$TARGET_DIR"; \
34+
cp -R /tmp/dist/. "$TARGET_DIR"; \
35+
fi; \
36+
sed \
37+
-e "s|__ROOT_REDIRECT_DIRECTIVE__|${ROOT_REDIRECT_DIRECTIVE}|g" \
38+
-e "s|__LOCATION_PATH__|${LOCATION_PATH}|g" \
39+
-e "s|__INDEX_FALLBACK__|${INDEX_FALLBACK}|g" \
40+
/tmp/nginx-docker.conf > /etc/nginx/conf.d/default.conf
41+
42+
EXPOSE 8080

README.md

Lines changed: 63 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,38 @@ To run this demo experiment locally, you will need to install node on your compu
1313
* To run locally, run `yarn serve`.
1414
* Go to [http://localhost:8080](http://localhost:8080) to view it in your browser. The page will reload when you make changes.
1515

16+
## Adding Tests
17+
18+
This repo uses two test types:
19+
20+
* **Unit tests** with **Vitest** for parser, utility, and component logic.
21+
* **End-to-end (E2E) tests** with **Playwright** for participant/designer flows in a running app.
22+
23+
### Unit tests (Vitest)
24+
25+
* Co-locate unit tests with the source file they cover.
26+
* Use the same base filename and add `.spec.` (for example: `src/parser/parser.ts` -> `src/parser/parser.spec.ts`).
27+
* Use `vitest` APIs (`describe`, `test`/`it`, `expect`).
28+
* Run unit tests with:
29+
30+
```bash
31+
yarn unittest
32+
```
33+
34+
### E2E tests (Playwright)
35+
36+
* Put E2E tests in the root `tests/` directory.
37+
* Name files with `.spec.ts` (for example: `tests/demo-vlat.spec.ts`).
38+
* Keep tests focused on user-observable behavior (navigation, input, progression, reviewer/designer behavior).
39+
* Run E2E tests with:
40+
41+
```bash
42+
yarn test
43+
```
44+
1645
## Release Instructions
1746

18-
Releasing reVISit.dev happens automatically when a PR is merged into the `main` branch. The name of the pull request should be the title of the release, e.g. `v1.0.0`. Releasing creates a tag with the same name as the PR, but the official GitGub release should be created manually. The `main` branch is protected and requires two reviews before merging.
47+
Releasing reVISit.dev happens automatically when a PR is merged into the `main` branch. The name of the pull request should be the title of the release, e.g. `v1.0.0`. Releasing creates a tag with the same name as the PR, but the official GitHub release should be created manually. The `main` branch is protected and requires two reviews before merging.
1948

2049
The workflow for release looks as follows:
2150
Develop features on feature branch
@@ -24,4 +53,36 @@ Dev branch
2453
| PR (1 per release)
2554
Main branch
2655
| Run release workflow on merge
27-
References are updated and commit is tagged
56+
References are updated and commit is tagged
57+
58+
### Release Follow-Up
59+
60+
- [ ] Verify docs links in the [Study Repository](https://github.com/revisit-studies/study) are up to date and point to the current reVISit documentation pages.
61+
- [ ] After the release is complete, run the template update process so downstream study templates include the latest release changes.
62+
63+
64+
## QC Checklist
65+
66+
### [Study Repository](https://github.com/revisit-studies/study)
67+
68+
**Studies**
69+
- [ ] Review all studies for any crashes/bugs
70+
- [ ] Check provenance data (audio, screen, etc.)
71+
72+
**File Download**
73+
- [ ] JSON export
74+
- [ ] Tidy download export
75+
- [ ] Download audio recordings
76+
- [ ] Download screen recordings
77+
- [ ] Download configs
78+
79+
**Docs**
80+
- [ ] Update comments in `store/types.ts`, `parser/types.ts`, `storage/types.ts`, `storage/engines/types.ts`
81+
- [ ] Update `typedocReadMe.md`
82+
83+
### [Documentation Repository](https://github.com/revisit-studies/reVISit-studies.github.io)
84+
- [ ] Review docs
85+
- [ ] Review [library list](https://revisit.dev/docs/designing-studies/plugin-libraries/)
86+
- [ ] Check for typos / outdated docs
87+
- [ ] Validate example code
88+
- [ ] Update screenshots

libraryDocGenerator.cjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ ${libraryConfig.additionalDescription ? `## Additional Description\n\n${libraryC
3535
3636
${forDocs
3737
? `<!-- Importing Links -->
38-
import StructuredLinks from '@site/src/components/StructuredLinks/StructuredLinks.tsx';
38+
import StructuredLinks from '@site/src/components/StructuredLinks/StructuredLinks.tsx';
3939
4040
<StructuredLinks
4141
demoLinks={[

libraryExampleStudyGenerator.cjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ const createExampleConfig = (libraryName) => ({
2525
authors: ['The reVISit Team'],
2626
date: new Date().toISOString().split('T')[0],
2727
description: `Example study using the ${libraryName} library.`,
28-
organizations: ['University of Utah', 'WPI', 'University of Toronto'],
28+
organizations: ['University of Utah', 'WPI'],
2929
},
3030
uiConfig: {
3131
contactEmail: '',

nginx-docker.conf

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
server {
2+
listen 8080;
3+
server_name _;
4+
5+
root /usr/share/nginx/html;
6+
index index.html;
7+
8+
location = / {
9+
__ROOT_REDIRECT_DIRECTIVE__
10+
}
11+
12+
location __LOCATION_PATH__ {
13+
try_files $uri __INDEX_FALLBACK__;
14+
}
15+
}

0 commit comments

Comments
 (0)