Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
110 commits
Select commit Hold shift + click to select a range
674e1c7
Added initial tag.
BanEvading Mar 27, 2025
184c577
Updating wording and stying
BanEvading Mar 27, 2025
578e404
Updating styling
BanEvading Mar 27, 2025
1d6a49f
Formatting
BanEvading Mar 27, 2025
67ea9b9
1.2.25
gearbox4026 Mar 27, 2025
6d311e4
Shuffles scouters.
BanEvading Mar 27, 2025
02447c3
Merge pull request #491 from Decatur-Robotics/signin-method-warning
renatodellosso Mar 27, 2025
64f6a66
1.2.25
gearbox4026 Mar 27, 2025
43dffca
Fixes Formatting
BanEvading Mar 27, 2025
7bf66b9
Merge pull request #492 from Decatur-Robotics/randomize-scouters
renatodellosso Mar 27, 2025
5198097
Initted Playwright
renatodellosso Mar 29, 2025
f53844e
Move old tests into tests/unit
renatodellosso Mar 29, 2025
a222904
Config web server for playwright
renatodellosso Mar 29, 2025
7898a8f
Add tests for index page
renatodellosso Mar 29, 2025
766450d
1.2.26
gearbox4026 Mar 29, 2025
c153ece
Update Jest configuration and CI workflows for Playwright tests
renatodellosso Mar 29, 2025
aa1a0af
Merge branch 'e2e-testing' of github.com:Decatur-Robotics/Gearbox int…
renatodellosso Mar 29, 2025
1691b78
Fix package.json formatting
renatodellosso Mar 29, 2025
1a34bce
Don't error if ROLLBAR_TOKEN isn't set
renatodellosso Mar 29, 2025
ae8a167
Update environment configuration and CI workflows for Playwright tests
renatodellosso Mar 29, 2025
a761475
Set up sign in function for e2e tests
renatodellosso Mar 30, 2025
b66169e
Use mongodb in e2e tests
renatodellosso Mar 30, 2025
5aebd52
No more Resend errors when API key is missing
renatodellosso Mar 30, 2025
aa4cf8c
Fewer Rollbar errors, no request helper constructor logs
renatodellosso Mar 30, 2025
a488833
Add API key check in request method and safeguard user ID assignment …
renatodellosso Mar 30, 2025
e510aec
Fix error in allCompetitionsToPairings when TBA is disabled
renatodellosso Mar 30, 2025
bfadfff
Add NextAuth vars to .env.test
renatodellosso Mar 30, 2025
59541de
[npm]: Bump jose from 6.0.8 to 6.0.10
dependabot[bot] Mar 31, 2025
513082d
[npm]: Bump react-icons from 5.4.0 to 5.5.0
dependabot[bot] Mar 31, 2025
8b3bd8b
1.2.26
gearbox4026 Mar 31, 2025
50d8704
1.2.26
gearbox4026 Mar 31, 2025
76d246a
Merge pull request #494 from Decatur-Robotics/dependabot/npm_and_yarn…
renatodellosso Mar 31, 2025
18d7a1e
Merge pull request #495 from Decatur-Robotics/dependabot/npm_and_yarn…
renatodellosso Mar 31, 2025
0403029
Merge branch 'main' into e2e-testing
renatodellosso Mar 31, 2025
c4410ed
Log Mongo connection string
renatodellosso Mar 31, 2025
3d612e6
Merge branch 'e2e-testing' of github.com:Decatur-Robotics/Gearbox int…
renatodellosso Mar 31, 2025
2b10cb1
Log on mongo connection
renatodellosso Mar 31, 2025
5b57044
Clean up uri determination
renatodellosso Mar 31, 2025
1057545
Changing
BanEvading Mar 31, 2025
76402d2
Making paragraph hidden
BanEvading Mar 31, 2025
008acf3
Fix sign in
renatodellosso Mar 31, 2025
6a38380
Tried to add an xs style, realized one shouldn't exist, not sure what…
BanEvading Mar 31, 2025
1e023b3
Removes the text on xs devices.
BanEvading Mar 31, 2025
cfa49d1
Adds break and makes the thing work
BanEvading Mar 31, 2025
6e7f841
Fixed some profile tests
renatodellosso Mar 31, 2025
f690bf6
Increase retries and workers for CI in Playwright configuration
renatodellosso Mar 31, 2025
9234dd2
almost got it working.
BanEvading Mar 31, 2025
bab7bae
export Reeefscape namespace
BanEvading Mar 31, 2025
3122e3b
got it /functional/ still lots of work to do
BanEvading Mar 31, 2025
eae7332
adding getMaximum
BanEvading Mar 31, 2025
ca22b80
fixing the math in GetMinimum
BanEvading Mar 31, 2025
ee987e3
switch from hardcode to parameter for determining calculated stat
BanEvading Mar 31, 2025
3ccbbe1
Add comments explaining what the functions do.
BanEvading Mar 31, 2025
fab5527
Change GetMaximum variable name from minimum to maximum
BanEvading Mar 31, 2025
e506998
Move labels below.
BanEvading Apr 1, 2025
e481a18
commit
BanEvading Apr 1, 2025
a5953b9
Don't add BASE_URL twice
renatodellosso Apr 1, 2025
3a42155
Add more stats
BanEvading Apr 1, 2025
a571a31
Shard playwright CI tests
renatodellosso Apr 1, 2025
cdb45f2
Remove hardcode in GetMax
BanEvading Apr 1, 2025
65e6b13
Change hardcode in check to based on stat
BanEvading Apr 1, 2025
a78dc1f
Update Playwright test command to use npm script
renatodellosso Apr 1, 2025
fe77851
Complete min/max coverage for auto
BanEvading Apr 1, 2025
e3924a9
Remove faulty stat
BanEvading Apr 1, 2025
36389f9
Update CI workflow to set permissions and modify Playwright test command
renatodellosso Apr 1, 2025
51c018d
Bump version to 1.3.0, add note about requiring individual shard in G…
renatodellosso Apr 1, 2025
e2bf7e6
Complete coverage for teleop.
BanEvading Apr 1, 2025
71f1ea5
Fix Breaking Typos
BanEvading Apr 1, 2025
8754455
Remove invalid stat
BanEvading Apr 1, 2025
bfcd395
Repeat tests in CI
renatodellosso Apr 1, 2025
53f7fdf
Change processor value to be more accurate.
BanEvading Apr 1, 2025
8dc29ae
1.2.27
gearbox4026 Apr 1, 2025
a73b9f9
Changing Types
BanEvading Apr 1, 2025
a3d1f38
Merge branch 'minimums-and-maximums-on-stat-page' of https://github.c…
BanEvading Apr 1, 2025
46fb7da
Remove export from Reefscape namespace
BanEvading Apr 1, 2025
418ff47
Remove import of now non-exported namespace
BanEvading Apr 1, 2025
be6bf80
Merge pull request #496 from Decatur-Robotics/minimums-and-maximums-o…
renatodellosso Apr 1, 2025
7e7324d
Merge branch 'main' into e2e-testing
renatodellosso Apr 1, 2025
0812bce
Fix signUp and signIn being flaky
renatodellosso Apr 1, 2025
3f845bf
Merge branch 'e2e-testing' of github.com:Decatur-Robotics/Gearbox int…
renatodellosso Apr 1, 2025
bcac56f
Tweak line breaks
renatodellosso Apr 1, 2025
563cc8e
Merge pull request #493 from Decatur-Robotics/e2e-testing
renatodellosso Apr 1, 2025
74dbe65
[npm]: Bump next from 15.2.3 to 15.2.4 in the npm_and_yarn group
dependabot[bot] Apr 2, 2025
a9dc744
1.3.1
gearbox4026 Apr 2, 2025
e17052e
Merge pull request #497 from Decatur-Robotics/dependabot/npm_and_yarn…
renatodellosso Apr 3, 2025
b086a3d
Add better API error logging
renatodellosso Apr 3, 2025
7e35f6d
Even better API error logging
renatodellosso Apr 3, 2025
9808034
Add avatar editing functionality
renatodellosso Apr 3, 2025
5526712
Ctrl + S
renatodellosso Apr 3, 2025
5aeba61
Add e2e test for avatar editing functionality
renatodellosso Apr 4, 2025
e79b2e6
Ctrl + S & added Title attribute to card
renatodellosso Apr 4, 2025
e1660bb
Add altText prop to Avatar component and add remaining e2e tests for …
renatodellosso Apr 4, 2025
cc3fa30
getAttribute -> toHaveAttribute
renatodellosso Apr 4, 2025
b1cfdb7
Level no longer displays above top bar
renatodellosso Apr 4, 2025
c062c78
Ctrl + S
renatodellosso Apr 4, 2025
3cecea6
Add ViewMatchesModal component and integrate it into CompHeaderCard
renatodellosso Apr 4, 2025
83b438a
Add key prop to ViewMatchCard in ViewMatchesModal
renatodellosso Apr 4, 2025
0baab92
Add export schedule as CSV, style my matches modal
renatodellosso Apr 4, 2025
9dbd7af
[npm]: Bump @eslint/js from 9.18.0 to 9.24.0
dependabot[bot] Apr 7, 2025
a6ae069
1.3.2
gearbox4026 Apr 7, 2025
860d331
[npm]: Bump resend from 4.1.2 to 4.2.0
dependabot[bot] Apr 7, 2025
58946df
1.3.2
gearbox4026 Apr 7, 2025
7c4a9aa
[npm]: Bump eslint-config-next from 15.2.2 to 15.2.4
dependabot[bot] Apr 7, 2025
fa719f0
1.3.2
gearbox4026 Apr 7, 2025
7995a3f
[npm]: Bump @serwist/next from 9.0.11 to 9.0.13
dependabot[bot] Apr 7, 2025
6bbd1f8
1.3.2
gearbox4026 Apr 7, 2025
cd9677b
Merge pull request #499 from Decatur-Robotics/dependabot/npm_and_yarn…
renatodellosso Apr 7, 2025
e96aab5
Merge pull request #500 from Decatur-Robotics/dependabot/npm_and_yarn…
renatodellosso Apr 7, 2025
9ae0c43
Merge pull request #501 from Decatur-Robotics/dependabot/npm_and_yarn…
renatodellosso Apr 7, 2025
132d65b
Merge pull request #502 from Decatur-Robotics/dependabot/npm_and_yarn…
renatodellosso Apr 7, 2025
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
4 changes: 3 additions & 1 deletion .env.production
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,6 @@
NEXT_PUBLIC_API_URL=/api/
NEXT_PUBLIC_SLACK_CLIENT_ID=10831824934.7404945710466
NEXT_PUBLIC_GOOGLE_ANALYTICS_ID=G-1BFJYBDC76
NEXT_PUBLIC_RECAPTCHA_KEY=6Le63OUqAAAAABxxDrbaU9OywDLLHqutVwbw7a9d
NEXT_PUBLIC_RECAPTCHA_KEY=6Le63OUqAAAAABxxDrbaU9OywDLLHqutVwbw7a9d

ENV_FILE=.env.production
15 changes: 13 additions & 2 deletions .env.test
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
NEXT_PUBLIC_API_URL=http://localhost:3000/api
NEXTAUTH_URL=http://localhost:3000/
NEXTAUTH_SECRET=testsecret

NEXT_PUBLIC_API_URL=/api/

DEVELOPER_EMAILS=["[email protected]"]

TOA_URL=https://example.com
TOA_APP_ID=123
TOA_KEY=456

DEFAULT_IMAGE=https://example.com/default.jpg
DEFAULT_IMAGE=https://example.com/default.jpg

BASE_URL_FOR_PLAYWRIGHT=http://localhost:3000/
ENABLE_TEST_SIGNIN_ROUTE=true
FALLBACK_MONGODB_URI=mongodb://127.0.0.1:27017/?directConnection=true&serverSelectionTimeoutMS=2000

ENV_FILE=.env.test

DB=playwright_tests
6 changes: 6 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,9 @@ jobs:

- name: Lint
run: npm run lint

e2e_test:
uses: ./.github/workflows/e2e_test.yml
permissions:
contents: read
pull-requests: write
71 changes: 71 additions & 0 deletions .github/workflows/e2e_test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
name: Playwright Tests
on: [workflow_dispatch, workflow_call]
jobs:
e2e_tests:
timeout-minutes: 60
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
# Make sure to require each shard in GitHub!
shardIndex: [1, 2, 3, 4]
shardTotal: [4]
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: lts/*

- name: Install dependencies
run: npm ci

- name: Install Playwright browsers
run: npx playwright install --with-deps

- name: Start MongoDB
uses: supercharge/[email protected]
with:
mongodb-version: "8.0"

- name: Run Playwright tests
run: npx cross-env NODE_ENV=test playwright test --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }}

- name: Upload blob report to GitHub Actions Artifacts
if: ${{ !cancelled() }}
uses: actions/upload-artifact@v4
with:
name: blob-report-${{ matrix.shardIndex }}
path: blob-report
retention-days: 1

merge_reports:
Comment on lines +5 to +42

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}
# Merge reports after playwright-tests, even if some shards have failed
if: ${{ !cancelled() }}
needs: [e2e_tests]

runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: lts/*
- name: Install dependencies
run: npm ci

- name: Download blob reports from GitHub Actions Artifacts
uses: actions/download-artifact@v4
with:
path: all-blob-reports
pattern: blob-report-*
merge-multiple: true

- name: Merge into HTML Report
run: npx playwright merge-reports --reporter html ./all-blob-reports

- name: Upload HTML report
uses: actions/upload-artifact@v4
with:
name: html-report--attempt-${{ github.run_attempt }}
path: playwright-report
retention-days: 14
Comment on lines +44 to +71

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}
9 changes: 8 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,11 @@ next-env.d.ts

# PWA
public/sw.js
public/swe-worker*
public/swe-worker*

# Playwright
node_modules/
/test-results/
/playwright-report/
/blob-report/
/playwright/.cache/
3 changes: 2 additions & 1 deletion .vscode/extensions.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"pmneo.tsimporter",
"austenc.tailwind-docs",
"bradlc.vscode-tailwindcss",
"Orta.vscode-jest"
"Orta.vscode-jest",
"ms-playwright.playwright"
]
}
11 changes: 6 additions & 5 deletions components/Avatar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import { BsGearFill } from "react-icons/bs";

export default function Avatar(props: {
user?: { image: string | undefined; level: number; admin?: boolean };
user?: { image: string | undefined; level?: number; admin?: boolean };
scale?: string | undefined; // Use "scale-75" for 75% scale, etc.
imgHeightOverride?: string | undefined;
showLevel?: boolean | undefined;
Expand All @@ -13,6 +13,7 @@
className?: string | undefined;
online?: boolean;
gearSize?: number;
altText?: string;
}) {
const { session, status } = useCurrentSession();
const user = props.user ?? session?.user;
Expand All @@ -24,8 +25,8 @@
<div
className={`avatar ${props.online && "online"} ${props.scale} ${props.className} ${props.animation}`}
>
{(props.showLevel ?? true) && (
<div className="absolute z-10 bg-base-100 rounded-tl-xl rounded-br-xl h-6 w-14 text-center text-sm font-semibold">
{props.showLevel && (
<div className="absolute bg-base-100 rounded-tl-xl rounded-br-xl h-6 w-14 text-center text-sm font-semibold">
LVL: {user?.level}
</div>
)}
Expand All @@ -33,13 +34,13 @@
className={`w-28 ${props.imgHeightOverride ?? "h-28"} rounded-xl border-${props.borderThickness ?? 4} ${levelClass}`}
>
<img
src={image}

Check failure

Code scanning / CodeQL

DOM text reinterpreted as HTML High

DOM text
is reinterpreted as HTML without escaping meta-characters.
alt={"Avatar"}
alt={props.altText ?? "Avatar"}
onClick={props.onClick}
></img>
</div>
{admin ? (
<div className="absolute z-10 -bottom-2 -left-2 text-slate-300 animate-spin-slow">
<div className="absolute -bottom-2 -left-2 text-slate-300 animate-spin-slow">
<BsGearFill size={props.gearSize ?? 36}></BsGearFill>
</div>
) : (
Expand Down
1 change: 1 addition & 0 deletions components/Card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export default function Card(props: CardProps) {

return (
<div
title={title}
className={`card bg-base-200 shadow-xl w-2/3 max-sm:w-full ${className}`}
>
{color ? (
Expand Down
68 changes: 68 additions & 0 deletions components/EditAvatarModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { useState } from "react";
import Card from "./Card";
import ClientApi from "@/lib/api/ClientApi";
import Avatar from "./Avatar";
import Image from "next/image";
import { Session } from "inspector/promises";
import toast from "react-hot-toast";

const api = new ClientApi();
export default function EditAvatarModal(props: {
currentImg: string;
close: () => void;
}) {
const [newAvatar, setNewAvatar] = useState<string>(props.currentImg);

async function updateAvatar() {
toast.promise(
api.changePFP(newAvatar).then(() => location.reload()),
{
loading: "Updating profile picture...",
success: "Successfully updated profile picture!",
error: "Failed to update profile picture!",
},
);
}

return (
<dialog
open={true}
className="modal"
>
<Card
title="Edit Avatar"
coloredTop="bg-secondary"
>
<div className="my-9 flex justify-center w-full">
<Avatar
user={{ image: newAvatar }}
scale="scale-150"
altText="New Avatar"
showLevel={false}
/>
</div>

<input
defaultValue={props.currentImg}
className="input"
onChange={(e) => setNewAvatar(e.target.value)}
placeholder="Enter new avatar url"
/>
<div className="flex gap-2 justify-start w-full">
<button
className="btn btn-primary mt-2"
onClick={updateAvatar}
>
Save
</button>
<button
className="btn btn-accent mt-2"
onClick={props.close}
>
Cancel
</button>
</div>
</Card>
</dialog>
);
}
8 changes: 7 additions & 1 deletion components/SignInMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,13 @@ function SignInCard() {
<div className="card-body">
<h1 className="card-title">Sign In</h1>
{error && <p className="text-error">{error}</p>}
<p>Choose a login provider</p>
<p className="italic">Choose a login provider</p>
<span>
You currently <span className="text-red-500">have</span> to sign-in
using either your{" "}
<span className="text-green-400">original sign-in method</span> or
your <span className="text-green-400">email.</span>
</span>
<div className="divider" />

<button
Expand Down
114 changes: 114 additions & 0 deletions components/ViewMatchesModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import { Match, Report } from "@/lib/Types";
import Card from "./Card";
import { User } from "../lib/Types";
import { match } from "assert";
import { report } from "process";
import Checkbox from "./forms/Checkboxes";
import { CheckmarkIcon } from "react-hot-toast";
import { useState } from "react";
import { toDict } from "@/lib/client/ClientUtils";

type MatchData = {
number: number;
url: string;
message: string;
completed: boolean;
subjective: boolean;
};

function ViewMatchCard(props: MatchData) {
return (
<Card
title={"Match " + props.number}
className="w-full"
>
{props.message}
<a
href={props.url}
className={`btn btn-sm ${props.completed ? `btn-ghost` : props.subjective ? `btn-secondary` : `btn-primary`}`}
>
{props.completed ? "Submitted" : "Click to scout"}
</a>
</Card>
);
}
export default function ViewMatchesModal(props: {
close: () => void;
matches: Match[];
reports: Report[];
user: User;
matchPathway: string;
}) {
const reportsById = toDict(props.reports);
const myMatches: MatchData[] = [];
const [showSubmittedReports, setShowSubmittedReports] = useState(false);

async function toggleShowSubmittedReports() {
setShowSubmittedReports(!showSubmittedReports);
}

for (const match of props.matches) {
if (match.subjectiveScouter == props.user._id?.toString()) {
myMatches.push({
number: match.number,
url: props.matchPathway + `/${match._id}/subjective`,
message: "You are subjective scouting match " + match.number + ".",
completed: match.assignedSubjectiveScouterHasSubmitted,
subjective: true,
});
}

for (const report of match.reports) {
if (reportsById[report]?.user == props.user._id?.toString()) {
myMatches.push({
number: match.number,
url: props.matchPathway + `/${report.toString()}`,
message:
"You are scouting team " +
reportsById[report].robotNumber +
" in match " +
match.number +
".",
completed: reportsById[report].submitted,
subjective: false,
});
}
}
}

return (
<dialog
open={true}
className="modal"
>
<Card title="My Matches">
<div className="absolute right-2 top-2 flex gap-4 items-center">
<div className="flex gap-2">
<div>Show Submitted Reports</div>
<input
type="checkbox"
onChange={toggleShowSubmittedReports}
className="checkbox checkbox-primary"
/>
</div>
<button
className="btn btn-sm btn-circle btn-ghost "
onClick={props.close}
>
</button>
</div>
<div className="overflow-y-scroll h-[650px]">
{myMatches
.filter((matchData) => showSubmittedReports || !matchData.completed)
.map((matchData, index) => (
<ViewMatchCard
{...matchData}
key={index}
/>
))}
</div>
</Card>
</dialog>
);
}
Loading