Skip to content
Merged

Dev #2828

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
163 commits
Select commit Hold shift + click to select a range
1a94e90
feature/AB#33563-AddPaymentScheduling
JamesPasta Aug 4, 2026
3fa612f
feature/AB#33652-ToolTip
JamesPasta Aug 5, 2026
1d81235
feature/AB#33824-AlphabeticalTemplates
JamesPasta Aug 6, 2026
1e5ece9
feature/AB#33850-FixedDTFooter
JamesPasta Aug 6, 2026
58ca329
AB#33877 fixes for worksheet checkbox handling in reporting
AndreGAot Aug 7, 2026
61300d7
AB#33877 address codeQL feedback
AndreGAot Aug 7, 2026
149cb26
[AB#33996] Change front-end FYE updates to use current year
plavoie-BC Aug 7, 2026
48dfa8e
[AB#33996] Add FYE column with SQL trigger
plavoie-BC Aug 7, 2026
18a0fe3
[AB#33996] Add FYE column binding to front-end
plavoie-BC Aug 7, 2026
7ed3b26
[AB#33996] Revert migration
plavoie-BC Aug 7, 2026
d82e968
[AB#33996] Add FYE Migration
plavoie-BC Aug 7, 2026
37a0708
[AB#33996] Add FYE Migration - First-Run Data Seeding
plavoie-BC Aug 7, 2026
2f0d701
[AB#33996] Support for FYE month format variations
plavoie-BC Aug 7, 2026
d5bbdfb
Merge remote-tracking branch 'origin/dev' into feature/AB#33996-appli…
plavoie-BC Aug 7, 2026
8b274d5
AB#33985 remove obsolete AI prompt assets
jacobwillsmith Aug 5, 2026
66b5089
AB#33985 move AI runtime config to database
jacobwillsmith Aug 5, 2026
010f998
AB#33985 rebuild AI models migration
jacobwillsmith Aug 5, 2026
c7dd97d
AB#33985 fix AIModels primary key migration
jacobwillsmith Aug 5, 2026
d6fcbb0
AB#33985 align AI model migration with dev
jacobwillsmith Aug 8, 2026
8ce08d6
AB#33985 align model seeding with unique name
jacobwillsmith Aug 8, 2026
c3c7a79
[AB#33996] Fix compute_applicants_fiscal_year_end SQL function
plavoie-BC Aug 10, 2026
7df777b
[AB#33996] Add FYE optional column to Grant Applicants List
plavoie-BC Aug 10, 2026
bfcaada
[AB#33653] Add External and Published Status Columns to Grant Applica…
plavoie-BC Aug 10, 2026
98a7e46
AB#33329 update how reporting configuration ordering is handled
AndreGAot Aug 10, 2026
5b88f13
Potential fix for pull request finding
AndreGAot Aug 10, 2026
535f02a
AB#33328 add some additional unit tests
AndreGAot Aug 10, 2026
c4a4107
Merge branch 'feature/AB#33329-reporting-configuration-ordering' of h…
AndreGAot Aug 10, 2026
ba9596e
AB#33979 - Moved AI Configuration tab to the AI module
hasanpour Aug 11, 2026
ccf3725
AB#33979 - Binded the back click handler with a closure-scoped callback
hasanpour Aug 11, 2026
8a9d90a
[AB#33653] SQ Quality Fixes
plavoie-BC Aug 11, 2026
092a990
[AB#33565] Tenant configuration localization for Grant Manager group
plavoie-BC Aug 11, 2026
2a738c8
[AB#33886] Bugfix for sort button layount on numeric and date type co…
plavoie-BC Aug 11, 2026
e852f3c
[AB#33914] Audit history widget should exclude initial published values
plavoie-BC Aug 11, 2026
1f5dd23
[AB#33914] CSS bugfix
plavoie-BC Aug 11, 2026
8cd298a
bugfix/AB#34036-CrashLoopAndSupplierException
JamesPasta Aug 11, 2026
4da18fb
bugfix/AB#34036-CrashLoopAndSupplierException-PS1update
JamesPasta Aug 11, 2026
78d8b6b
Merge pull request #2779 from bcgov/feature/AB#33996-applicant-FYE-co…
JamesPasta Aug 11, 2026
7670a79
Merge pull request #2777 from bcgov/bugfix/AB#33877-report-view-error
JamesPasta Aug 11, 2026
395c266
Merge pull request #2782 from bcgov/feature/ai-prompt-assets-cleanup-…
JamesPasta Aug 11, 2026
cc34faf
Merge pull request #2784 from bcgov/feature/AB#33653-status-columns
JamesPasta Aug 11, 2026
0978647
AB#32831 init CLAUDE md and update for project
AndreGAot Aug 11, 2026
feaa019
Merge pull request #2786 from bcgov/feature/AB#33329-reporting-config…
JamesPasta Aug 11, 2026
bf7e678
Merge pull request #2787 from bcgov/bugfix/AB#33979-Back-button-AI-ta…
JamesPasta Aug 11, 2026
595bfa6
bugfix/AB#34036-CrashLoopAndSupplierException-AIReview
JamesPasta Aug 11, 2026
70f161d
Merge pull request #2791 from bcgov/bugfix/AB#34036-Crashloop
JamesPasta Aug 11, 2026
9d1f0f4
AB#32831 remove watermark check
AndreGAot Aug 11, 2026
0dd08d3
Apply suggestions from code review
AndreGAot Aug 11, 2026
c91bc38
Merge pull request #2790 from bcgov/bugfix/AB#33914-audit-history
JamesPasta Aug 11, 2026
9e58736
feature/AB#33985-FixDBMigrator
JamesPasta Aug 11, 2026
3beaa90
feature/AB#33985-FixDBMigrator
JamesPasta Aug 11, 2026
9c7ea76
AB#33983 update AI architecture documentation
jacobwillsmith Aug 5, 2026
6c01a8d
AB#33983 correct AI operation contracts
jacobwillsmith Aug 12, 2026
bf6b69b
Merge pull request #2793 from bcgov/feature/AB#33985-FixAITables
JamesPasta Aug 12, 2026
068f14f
Merge pull request #2792 from bcgov/feature/AB#32831-add-claudemd
JamesPasta Aug 12, 2026
8b0fe86
AB#33983 address documentation review
jacobwillsmith Aug 12, 2026
8420698
Merge remote-tracking branch 'origin/dev' into bugfix/AB#33850-CSS-No…
JamesPasta Aug 12, 2026
3a0c700
Merge pull request #2796 from bcgov/bugfix/AB#33850-CSS-NotifcationsL…
JamesPasta Aug 12, 2026
8444080
bugfix/AB#33870-DBMigrationFix
JamesPasta Aug 12, 2026
fd34aaa
Merge remote-tracking branch 'origin/dev' into bugfix/AB#33870-DBMigr…
JamesPasta Aug 12, 2026
8bb3960
Merge pull request #2798 from bcgov/bugfix/AB#33870-DBMigrationsFix
JamesPasta Aug 12, 2026
1071806
bugfix/AB#33850-CSS-NotifcationsIssueWithModal
JamesPasta Aug 12, 2026
0e69767
Merge remote-tracking branch 'origin/dev' into bugfix/AB#33850-CSS-No…
JamesPasta Aug 12, 2026
198a109
Merge pull request #2800 from bcgov/bugfix/AB#33850-CSS-NotifcationsL…
JamesPasta Aug 12, 2026
d32f249
Merge pull request #2794 from bcgov/feature/AB#33983-architecture-doc…
JamesPasta Aug 12, 2026
e04b528
Merge pull request #2802 from bcgov/feature/AB#33824-AlphabeticalTemp…
JamesPasta Aug 12, 2026
89923b6
[AB33234] Add renewal link support to ApplicationForm and DTOs
plavoie-BC Aug 12, 2026
2498692
Merge pull request #2803 from bcgov/feature/AB#33563-AddPaymentEventS…
JamesPasta Aug 12, 2026
59e852c
Merge pull request #2804 from bcgov/feature/AB#33652-ToolTIP
JamesPasta Aug 12, 2026
f6cb782
[AB#33234] Add renewal link DbMigration
plavoie-BC Aug 12, 2026
37d836e
Merge remote-tracking branch 'origin/dev' into feature/AB#33234-renew…
plavoie-BC Aug 12, 2026
6c7ef82
Revert "[AB#33234] Add renewal link DbMigration"
plavoie-BC Aug 13, 2026
b09d4b4
[AB#33234] Add ExternalLinks collection to DbMigration
plavoie-BC Aug 13, 2026
869c87d
[AB#33234] Map External Links to Submission Info Data Provider
plavoie-BC Aug 13, 2026
95c825e
[AB#33234] Fix ExternalLinkType reference
plavoie-BC Aug 13, 2026
080403b
[AB#33234] Reset migration to resolve conflict
plavoie-BC Aug 13, 2026
498b766
[AB#33234] Refactor ExternalLink
plavoie-BC Aug 13, 2026
e24e7c8
[AB#33234] Add EligibleForRenewal to Application
plavoie-BC Aug 13, 2026
b0251e5
[AB#33234] Optimize ExternalLink queries to DB
plavoie-BC Aug 13, 2026
af5728b
[AB#33234] Related Links should sort ascending except for negatives
plavoie-BC Aug 13, 2026
f3edea2
[AB#33234] Add backend ExternalLink AppService and Validation
plavoie-BC Aug 13, 2026
d7eea40
AB#33821 - Added legal disclaimer modal
hasanpour Aug 13, 2026
8788800
AB#33553: Wrong Tenant Error Page
aurelio-aot Aug 13, 2026
19d81b6
AB#33821 - Fixed camelCase file refrence
hasanpour Aug 13, 2026
5584ae6
AB#34091 fix the reporting delete module overlay
AndreGAot Aug 13, 2026
3b230f0
[AB#33234] Fix ExternalLink default in JSON column
plavoie-BC Aug 13, 2026
17544ae
AB#33815 - Added backend
hasanpour Aug 13, 2026
5605b37
AB#33815 - Added UI
hasanpour Aug 13, 2026
c98fbbd
AB#33815 - Gating wiring
hasanpour Aug 13, 2026
453938a
AB#33815 - Fixed AI Reporting permission gap
hasanpour Aug 13, 2026
47e916e
AB#33815 - Localized AISettingGroup
hasanpour Aug 13, 2026
a067f14
Merge pull request #2812 from bcgov/bugfix/AB34091-reporting-config-o…
AndreGAot Aug 13, 2026
2b6aa72
[AB#33234] Add UI for managing applicant portal external links
plavoie-BC Aug 13, 2026
02080a8
AB#33815 - Fixed menu item visibility for ITAdmin
hasanpour Aug 13, 2026
fe85aa2
[AB#33234] Form Configuration UI Changes
plavoie-BC Aug 13, 2026
433f390
[AB#34096] Fix ApplicationFormVersion update functions
plavoie-BC Aug 13, 2026
bd77d48
Merge pull request #2814 from bcgov/bugfix/AB#34096-form-exception
JamesPasta Aug 13, 2026
61888fc
AB#34056 update policy for user assignment
AndreGAot Aug 14, 2026
b63f825
AB#34100 fix program details display logic
AndreGAot Aug 14, 2026
ef913dd
AB#33864 implement AI mapping worksheet suggestion flow
jacobwillsmith Aug 5, 2026
eaadb8f
AB#33864 guide independent mapping and worksheet flow
jacobwillsmith Aug 5, 2026
b7dcd68
AB#33864 consolidate AI review workflow migrations
jacobwillsmith Aug 6, 2026
327c2fc
AB#33864 refine AI mapping worksheet review flow
jacobwillsmith Aug 7, 2026
3b1d12b
AB#33864 remove migration history reconciliation
jacobwillsmith Aug 7, 2026
9b5f24a
AB#33864 normalize mapping assets after rebase
jacobwillsmith Aug 12, 2026
c42b164
AB#33864 add AI scoresheet suggestion review flow
jacobwillsmith Aug 13, 2026
b7549e3
AB#33864 fix worksheet review test fixtures
jacobwillsmith Aug 13, 2026
87af0c1
AB#33864 improve AI suggestion review flow
jacobwillsmith Aug 13, 2026
841945f
AB#33864 correct AI flow reset cleanup
jacobwillsmith Aug 13, 2026
3e83925
AB#33864 clean up AI review warnings
jacobwillsmith Aug 13, 2026
d3c39a2
AB#33864 fix remaining SonarCloud guard
jacobwillsmith Aug 13, 2026
94474b2
AB#33864 clean nullable warnings in AI tests
jacobwillsmith Aug 13, 2026
fd33dd4
AB#33864 fix AI test compile errors
jacobwillsmith Aug 13, 2026
19541b8
AB#33864 fix prompt seeder test mock
jacobwillsmith Aug 13, 2026
f7b2856
AB#33864 stabilize prompt seeder test
jacobwillsmith Aug 13, 2026
6f834db
AB#33864 match prompt repository overloads
jacobwillsmith Aug 13, 2026
5e07a65
AB#33864 address AI review workflow findings
jacobwillsmith Aug 13, 2026
0a18172
AB#33864 stabilize prompt seeder regression test
jacobwillsmith Aug 13, 2026
f694c67
AB#33864 align scoresheet seed assertion
jacobwillsmith Aug 13, 2026
9c8c89b
AB#33864 finalize AI review workflow
jacobwillsmith Aug 14, 2026
f007732
Merge pull request #2815 from bcgov/bugfix/AB#34100-program-details-m…
JamesPasta Aug 14, 2026
20c7fca
Merge pull request #2813 from bcgov/feature/AB#33815-AI-Reporting-Toggle
JamesPasta Aug 14, 2026
a977425
Merge pull request #2811 from bcgov/bugfix/AB#33553-Wrong-Tenant-Message
JamesPasta Aug 14, 2026
ebf9834
bugfix/AB#34067 - Fix Cypress lists
velang01 Aug 14, 2026
715526e
bugfix/AB#34092-ImportUserBroken
JamesPasta Aug 14, 2026
389f884
Merge pull request #2816 from bcgov/bugfix/AB#34092-Import-User-Broke…
JamesPasta Aug 14, 2026
186556c
Merge pull request #2809 from bcgov/feature/AB#33864-ai-mapping-works…
JamesPasta Aug 14, 2026
d2b629a
AB#33864 propagate worksheet generation failures
jacobwillsmith Aug 14, 2026
05d1eba
AB#33864 preserve deferred scoresheet review action
jacobwillsmith Aug 14, 2026
d014fdc
AB#33864 split scoresheet generate and review actions
jacobwillsmith Aug 14, 2026
48355b2
AB#33864 use native JSON parsing in mapping
jacobwillsmith Aug 14, 2026
27ffddb
AB#33864 log saved mapping apply failures
jacobwillsmith Aug 14, 2026
ba2096e
inital commit
Aug 14, 2026
cd12809
feature/AB#33998-AttachementScheduleNotifications
JamesPasta Aug 14, 2026
30518fb
feature/AB#33998-AttachementScheduleNotifications
JamesPasta Aug 14, 2026
74fc46c
feature/AB#33998-AttachementScheduleNotifications-Sonar
JamesPasta Aug 14, 2026
bfe480c
Merge pull request #2819 from bcgov/feature/AB#33998-AttachmentSchedu…
JamesPasta Aug 14, 2026
ae7d26d
feature/AB#33998-AttachementScheduleNotifications-Sonar
JamesPasta Aug 14, 2026
af0f2ba
Make ApprovalFlow.cy.ts self-seeding and fix transient CAS token failure
Aug 14, 2026
2a24d45
feature/AB#33998-AttachementScheduleNotifications-Sonar
JamesPasta Aug 14, 2026
3d87df8
Merge pull request #2821 from bcgov/feature/AB#33998-AttachmentSchedu…
JamesPasta Aug 14, 2026
bf86bce
Merge pull request #2822 from bcgov/bugfix/AB#34108_fix_approval_flow…
DarylTodosichuk Aug 17, 2026
a792001
[AB#33234] Fix ApplicationForm Unit Tests
plavoie-BC Aug 17, 2026
eded394
Merge remote-tracking branch 'origin/dev' into feature/AB#33234-renew…
plavoie-BC Aug 17, 2026
6da1cc2
Merge pull request #2818 from bcgov/feature/AB#33864-sonar-issue-cleanup
JamesPasta Aug 17, 2026
6f45237
initial commit to push the changes to fix the approval flow seeder
Aug 17, 2026
b089f9d
Merge pull request #2823 from bcgov/feature/AB#34056-new-tenant-creat…
JamesPasta Aug 17, 2026
0a990d8
bugfix/AB#34018_fix_approval_seeder - Multi-platform compatibility. N…
Stephan-McColm Aug 17, 2026
ae8afee
AB#33864 AI form scoresheet/worksheet/mapping flow standardization
jacobwillsmith Aug 17, 2026
ec8b41f
AB#33864 Fix AI workflow review findings
jacobwillsmith Aug 18, 2026
f259a42
AB#33864 Simplify AI button guards
jacobwillsmith Aug 18, 2026
e34fa99
Merge pull request #2825 from bcgov/feature/AB#33864-pending-ai-score…
jacobwillsmith Aug 18, 2026
5c1c2d4
Merge pull request #2824 from bcgov/bugfix/AB#34108_fix_approval_seeder
DarylTodosichuk Aug 18, 2026
2ff04d8
[AB#33234] Code Quality Fixes
plavoie-BC Aug 18, 2026
2627d16
Merge remote-tracking branch 'origin/dev' into feature/AB#33234-renew…
plavoie-BC Aug 18, 2026
c02afd3
[AB#33234] Application Forms UI Small Fixes
plavoie-BC Aug 18, 2026
347d370
Merge pull request #2806 from bcgov/feature/AB#33234-renewal-link
AndreGAot Aug 18, 2026
2f8eea0
feature/AB#33297_Modify_Cypress_Launcher: Improved support for local …
Stephan-McColm Aug 18, 2026
e6643f4
Merge pull request #2826 from bcgov/feature/AB#33297_Modify_Cypress_L…
DarylTodosichuk Aug 18, 2026
0b62d54
AB#33935 update links structure for Applicant Portal
AndreGAot Aug 18, 2026
770d436
AB#33935 add migration for application forms extra properties
AndreGAot Aug 18, 2026
b8edc82
AB#33935 fix unit tests
AndreGAot Aug 18, 2026
e28373d
AB#33935 update migration
AndreGAot Aug 18, 2026
c14effd
Merge pull request #2827 from bcgov/feature/AB#33935-renewal-link-upd…
AndreGAot Aug 18, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -118,4 +118,9 @@ appsettings.json

/applications/Orchestrator
*.env
/applications/Unity.GrantManager/src/Unity.GrantManager.Web/package-lock.json
/applications/Unity.GrantManager/src/Unity.GrantManager.Web/package-lock.json
/applications/Unity.AutoUI/cypress/config/dev.json
/applications/Unity.AutoUI/cypress/config/dev2.json
/applications/Unity.AutoUI/cypress/config/test.json
/applications/Unity.AutoUI/cypress/config/uat.json
/applications/Unity.AutoUI/cypress/config/prod.json
63 changes: 63 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

> This is **Unity Portal**, a grant management system for the Province of British Columbia. It is NOT the Unity game engine — do not suggest UnityEngine APIs.

## Repository Layout

`applications/Unity.GrantManager/` is where almost all work happens — a self-contained ABP Framework solution with its own extensive AI-agent instructions. `applications/Unity.AutoUI/` holds Cypress E2E tests; `applications/Unity.Tools/`, `database/`, and `documentation/` round out the rest (see root `README.md` for the full layout).

**Read these before making non-trivial changes in `applications/Unity.GrantManager/`** — note this solution has its own `.github/`, separate from the root `.github/` above it:

- `applications/Unity.GrantManager/.github/copilot-instructions.md` — authoritative project overview, layering, and conventions (trust this first)
- `applications/Unity.GrantManager/.github/instructions/*.instructions.md` — path-scoped rules for C#, EF Core, JavaScript, security, testing
- `applications/Unity.GrantManager/.github/skills/*/SKILL.md` — deep-dive patterns: DDD, application layer, EF Core, testing, ABP CLI, module structure
- `applications/Unity.GrantManager/.github/agents/*.agent.md` — planning agents for features, DDD modeling, EF migrations, permissions/localization audits, test strategy, PR readiness

Where those files and this one overlap, prefer the more specific ones under `applications/Unity.GrantManager/.github/`.

## Build & Test

All commands run from `applications/Unity.GrantManager/`:

```bash
dotnet restore Unity.GrantManager.sln
dotnet build Unity.GrantManager.sln --no-restore # ~3 min, 81 projects
dotnet test Unity.GrantManager.sln --no-build # ~470 tests, ~1-2 min

# Single test project
dotnet test test/Unity.GrantManager.Application.Tests/ --no-build
```

- No PostgreSQL setup needed for tests — SQLite in-memory (most projects) or `EFCore.InMemory` (`Unity.GrantManager.Web.Tests`).
- `Unity.GrantManager.Web/Pages/Dashboard/Index.cshtml.cs` has one expected `CS8604` warning — don't fix it unless asked.
- `Directory.Build.props` / `common.props` (repo-wide MSBuild props) already suppress `NU1701`, `MSB3277`, `CS1591` — don't re-suppress per-project.

### Local dev environment

`docker-compose.yml` + `.env.example` in `applications/Unity.GrantManager/` spin up the web app, PostgreSQL, a DB migrator, and Redis. Copy `.env.example` to `.env` and fill in secrets before running `docker compose up`.

### EF Core migrations

There are **two separate database contexts** — always specify which one:

```bash
cd applications/Unity.GrantManager/src/Unity.GrantManager.EntityFrameworkCore

dotnet ef migrations add <Name> --context GrantManagerDbContext --output-dir Migrations/HostMigrations # host/shared tables
dotnet ef migrations add <Name> --context GrantTenantDbContext --output-dir Migrations/TenantMigrations # per-tenant data
```

## Architecture

ABP Framework modular monolith, DDD-layered — see `applications/Unity.GrantManager/.github/copilot-instructions.md` and `applications/Unity.GrantManager/.github/skills/unity-module-structure/SKILL.md` for the full module list and dependency-direction diagram.

Business rules belong in Domain entities/managers, not controllers or app services. Don't call another app service within the same module — push shared logic into a domain service.

### Key conventions

C#, EF Core, JavaScript, security, and testing conventions are detailed in `.claude/rules/*.md` (loaded automatically for matching files) and `applications/Unity.GrantManager/.github/instructions/*.instructions.md`.

- **Branching**: `dev` → `test` → `main` promotion. Feature branches `feature/*`, fixes `bugfix/*`, urgent `hotfix/*`. PRs to `dev` come from `feature/*`/`bugfix/*`/`hotfix/*`; PRs to `main` only from `test` or `hotfix/*`.
- **Commit messages**: prefix with `[AB#<ID>]` extracted from the branch name (e.g. `feature/AB#32037-...` → `AB#32037`), then a short description.
3 changes: 2 additions & 1 deletion applications/Unity.AutoUI/CypressTestLauncher.bat
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
@echo off
@echo off
setlocal
cd /d "%~dp0"

powershell -NoProfile -ExecutionPolicy Bypass -NoExit -Command "$ErrorActionPreference='Stop';$ProgressPreference='SilentlyContinue';Add-Type -AssemblyName System.Windows.Forms;Add-Type -AssemblyName System.Drawing;$projectPath=(Get-Location).Path;$form=New-Object System.Windows.Forms.Form;$form.Text='Cypress Test Launcher';$form.Size=New-Object System.Drawing.Size(420,240);$form.StartPosition='CenterScreen';$form.AutoScaleMode=[System.Windows.Forms.AutoScaleMode]::None;$envLabel=New-Object System.Windows.Forms.Label;$envLabel.Text='Select Environment:';$envLabel.AutoSize=$true;$envLabel.Location=New-Object System.Drawing.Point(15,15);$envBox=New-Object System.Windows.Forms.ComboBox;$envBox.Location=New-Object System.Drawing.Point(15,35);$envBox.Size=New-Object System.Drawing.Size(380,25);$envBox.DropDownStyle='DropDownList';$envBox.Items.Add('Please select an environment');$envBox.Items.Add('DEV');$envBox.Items.Add('DEV2');$envBox.Items.Add('TEST');$envBox.Items.Add('UAT');$envBox.Items.Add('PROD');$envBox.SelectedIndex=0;$modeLabel=New-Object System.Windows.Forms.Label;$modeLabel.Text='Select Mode:';$modeLabel.AutoSize=$true;$modeLabel.Location=New-Object System.Drawing.Point(15,70);$modeBox=New-Object System.Windows.Forms.ComboBox;$modeBox.Location=New-Object System.Drawing.Point(15,90);$modeBox.Size=New-Object System.Drawing.Size(380,25);$modeBox.DropDownStyle='DropDownList';$modeBox.Items.Add('Please select a mode');$modeBox.Items.Add('GUI');$modeBox.Items.Add('Headless');$modeBox.SelectedIndex=0;$run=New-Object System.Windows.Forms.Button;$run.Text='Launch Cypress';$run.Location=New-Object System.Drawing.Point(15,135);$run.Size=New-Object System.Drawing.Size(380,32);$run.Add_Click({try{if($envBox.SelectedIndex -eq 0 -or $modeBox.SelectedIndex -eq 0){[System.Windows.Forms.MessageBox]::Show('Please select both an environment and a mode.','Missing Selection');return};Set-Location $projectPath;$envName=$envBox.SelectedItem;$envFile='.\\cypress.'+$envName+'.env.json';if(Test-Path $envFile){Copy-Item $envFile '.\\cypress.env.json' -Force}else{[System.Windows.Forms.MessageBox]::Show('Environment file not found: '+$envFile,'Missing Env File');return};if($modeBox.SelectedItem -eq 'Headless'){Start-Process powershell -ArgumentList '-NoExit','-Command',\"cd '$projectPath'; npx cypress run\"}else{Start-Process powershell -ArgumentList '-NoExit','-Command',\"cd '$projectPath'; npx cypress open\"}}catch{[System.Windows.Forms.MessageBox]::Show($_.Exception.Message,'Cypress Launcher Error')}});$form.Controls.Add($envLabel);$form.Controls.Add($envBox);$form.Controls.Add($modeLabel);$form.Controls.Add($modeBox);$form.Controls.Add($run);$form.ShowDialog()"
powershell -NoProfile -ExecutionPolicy Bypass -NoExit -Command "$ErrorActionPreference='Stop';$ProgressPreference='SilentlyContinue';Add-Type -AssemblyName System.Windows.Forms;Add-Type -AssemblyName System.Drawing;$projectPath=(Get-Location).Path;$form=New-Object System.Windows.Forms.Form;$form.Text='Cypress Test Launcher';$form.Size=New-Object System.Drawing.Size(420,240);$form.StartPosition='CenterScreen';$form.AutoScaleMode=[System.Windows.Forms.AutoScaleMode]::None;$envLabel=New-Object System.Windows.Forms.Label;$envLabel.Text='Select Environment:';$envLabel.AutoSize=$true;$envLabel.Location=New-Object System.Drawing.Point(15,15);$envBox=New-Object System.Windows.Forms.ComboBox;$envBox.Location=New-Object System.Drawing.Point(15,35);$envBox.Size=New-Object System.Drawing.Size(380,25);$envBox.DropDownStyle='DropDownList';$envBox.Items.Add('Please select an environment');$envBox.Items.Add('DEV');$envBox.Items.Add('DEV2');$envBox.Items.Add('TEST');$envBox.Items.Add('UAT');$envBox.Items.Add('PROD');$envBox.SelectedIndex=0;$modeLabel=New-Object System.Windows.Forms.Label;$modeLabel.Text='Select Mode:';$modeLabel.AutoSize=$true;$modeLabel.Location=New-Object System.Drawing.Point(15,70);$modeBox=New-Object System.Windows.Forms.ComboBox;$modeBox.Location=New-Object System.Drawing.Point(15,90);$modeBox.Size=New-Object System.Drawing.Size(380,25);$modeBox.DropDownStyle='DropDownList';$modeBox.Items.Add('Please select a mode');$modeBox.Items.Add('GUI');$modeBox.Items.Add('Headless');$modeBox.SelectedIndex=0;$run=New-Object System.Windows.Forms.Button;$run.Text='Launch Cypress';$run.Location=New-Object System.Drawing.Point(15,135);$run.Size=New-Object System.Drawing.Size(380,32);$run.Add_Click({try{if($envBox.SelectedIndex -eq 0 -or $modeBox.SelectedIndex -eq 0){[System.Windows.Forms.MessageBox]::Show('Please select both an environment and a mode.','Missing Selection');return};Set-Location $projectPath;$envName=$envBox.SelectedItem.ToString().ToLowerInvariant();$envFile=Join-Path $projectPath ('cypress\config\'+$envName+'.json');if(-not (Test-Path $envFile)){[System.Windows.Forms.MessageBox]::Show('Environment file not found: '+$envFile,'Missing Env File');return};if($modeBox.SelectedItem -eq 'Headless'){Start-Process powershell -ArgumentList '-NoExit','-ExecutionPolicy','Bypass','-Command',\"`$env:UNITY_CYPRESS_ENV='$envName'; cd '$projectPath'; node .\\scripts\\run-cypress.js run --browser chrome\"}else{Start-Process powershell -ArgumentList '-NoExit','-ExecutionPolicy','Bypass','-Command',\"`$env:UNITY_CYPRESS_ENV='$envName'; cd '$projectPath'; node .\\scripts\\run-cypress.js open --browser chrome\"}}catch{[System.Windows.Forms.MessageBox]::Show($_.Exception.Message,'Cypress Launcher Error')}});$form.Controls.Add($envLabel);$form.Controls.Add($envBox);$form.Controls.Add($modeLabel);$form.Controls.Add($modeBox);$form.Controls.Add($run);$form.ShowDialog()"
33 changes: 32 additions & 1 deletion applications/Unity.AutoUI/cypress.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,30 @@ import FormData from "form-data";
import fs from "fs";
import path from "path";

function loadLocalEnvironmentConfig(): Record<string, unknown> {
const environmentName = (
process.env.UNITY_CYPRESS_ENV || "dev"
).toLowerCase();
const environmentFilePath = path.resolve(
"cypress",
"config",
`${environmentName}.json`,
);

try {
const content = fs.readFileSync(environmentFilePath, "utf-8");
return JSON.parse(content) as Record<string, unknown>;
} catch {
return {};
}
}

// https://docs.cypress.io/guides/references/configuration
export default defineConfig({
e2e: {
setupNodeEvents(on) {
setupNodeEvents(on, config) {
const environmentConfig = loadLocalEnvironmentConfig();

on("task", {
readJsonIfExists(filePath: string): Record<string, unknown> | null {
try {
Expand Down Expand Up @@ -59,6 +79,17 @@ export default defineConfig({
return response.json();
},
});

return {
...config,
baseUrl:
(environmentConfig["webapp.url"] as string | undefined) ||
config.baseUrl,
env: {
...config.env,
...environmentConfig,
},
};
},
specPattern: [
"cypress/e2e/**/*.cy.{js,jsx,ts,tsx}",
Expand Down
3 changes: 2 additions & 1 deletion applications/Unity.AutoUI/cypress/config/dev.json.example
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@
"test2password": "",
"TEST_EMAIL_TO": "",
"TEST_EMAIL_CC": "",
"TEST_EMAIL_BCC": ""
"TEST_EMAIL_BCC": "",
"chefsApiKey": ""
}
3 changes: 2 additions & 1 deletion applications/Unity.AutoUI/cypress/config/test.json.example
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@
"test2password": "",
"TEST_EMAIL_TO": "",
"TEST_EMAIL_CC": "",
"TEST_EMAIL_BCC": ""
"TEST_EMAIL_BCC": "",
"chefsApiKey": ""
}
3 changes: 2 additions & 1 deletion applications/Unity.AutoUI/cypress/config/uat.json.example
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@
"test2password": "",
"TEST_EMAIL_TO": "",
"TEST_EMAIL_CC": "",
"TEST_EMAIL_BCC": ""
"TEST_EMAIL_BCC": "",
"chefsApiKey": ""
}
35 changes: 19 additions & 16 deletions applications/Unity.AutoUI/cypress/e2e/lists.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,31 +10,34 @@ describe('Grant Manager Login and List Navigation', () => {
const appsPage = ApplicationsPageInstance()

function setDashboardIntakeToTestIfAvailable() {
const btnSel = 'button[data-id="dashboardIntakeId"]'
const listboxSel = '#bs-select-1[role="listbox"]'
const searchSel = 'input[type="search"][aria-controls="bs-select-1"]'

cy.get(btnSel, { timeout: 30000 })
// The INTAKES filter is a Select2 (bootstrap-5 theme) multi-select, not
// bootstrap-select — the toggle is the [role="combobox"] wrapping the
// rendered-choices <ul id="select2-dashboardIntakeId-container">.
const renderedSel = '#select2-dashboardIntakeId-container'
const dropdownSel = '.select2-dropdown'
const optionSel = `${dropdownSel} li.select2-results__option`

cy.get(renderedSel, { timeout: 30000 })
.should('be.visible')
.first()
.closest('[role="combobox"]')
.as('intakeCombobox')
.click({ force: true })

cy.get(listboxSel, { timeout: 30000 }).should('be.visible')
cy.get(dropdownSel, { timeout: 30000 }).should('be.visible')

cy.get(searchSel, { timeout: 30000 })
cy.get(renderedSel)
.parent()
.find('textarea.select2-search__field', { timeout: 30000 })
.should('be.visible')
.clear()
.type('Test')

cy.contains(`${listboxSel} a.dropdown-item[role="option"] span.text`, /^Test$/, { timeout: 30000 })
.closest('a.dropdown-item')
cy.contains(optionSel, /^Test$/, { timeout: 30000 })
.then(($opt) => {
const selected =
$opt.attr('aria-selected') === 'true' ||
$opt.hasClass('selected')
const selected = $opt.attr('aria-selected') === 'true'

if (!selected) {
cy.wrap($opt).scrollIntoView().click({ force: true })
cy.wrap($opt).click({ force: true })
}
})

Expand All @@ -43,8 +46,8 @@ describe('Grant Manager Login and List Navigation', () => {
expect(texts).to.include('Test')
})

cy.get(btnSel).first().click({ force: true })
cy.get(btnSel).first().should('have.attr', 'aria-expanded', 'false')
cy.get('@intakeCombobox').click({ force: true })
cy.get('@intakeCombobox').should('have.attr', 'aria-expanded', 'false')
}

it('Verify Login', () => {
Expand Down
4 changes: 2 additions & 2 deletions applications/Unity.AutoUI/cypress/e2e/login.cy.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/// <reference types="cypress" />
import { LoginPageInstance, NavigationPageInstance } from "../utilities";

describe('Grant Manager Login and Logout', () => {
Expand All @@ -8,10 +9,9 @@ describe('Grant Manager Login and Logout', () => {
loginPage.login()
loginPage.verifyOnGrantApplications()

// Verify Default Grant Program tenant is selected
navPage.switchToDefaultGrantsProgramIfAvailable()
navPage.verifyCurrentTenant('Default Grants Program')

// Logout (terminal action)
loginPage.quickLogout()
})
})
3 changes: 1 addition & 2 deletions applications/Unity.AutoUI/cypress/e2e/navigation.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,9 @@ describe('Grant Manager Login and Top Navigation', () => {

it('Verify navigation options in the top banner', () => {

// 3.) Verify Default Grant Program tenant is selected.
navPage.switchToDefaultGrantsProgramIfAvailable()
navPage.verifyCurrentTenant('Default Grants Program')

// 4.) Ensure all expected headings are present.
navPage.verifyAllNavItemsExist()

// 5.) Applications
Expand Down
2 changes: 1 addition & 1 deletion applications/Unity.AutoUI/cypress/fixtures/metabase.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
},
{
"unityEnv": "PROD",
"baseURL": "https://unity-reporting.apps.gold.devops.gov.bc.ca/"
"baseURL": "https://unity-reporting.apps.silver.devops.gov.bc.ca/"
}
]
}
40 changes: 37 additions & 3 deletions applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -506,10 +506,25 @@ const APPLICATIONS_PATH = "GrantApplications";
return;
}

// Priority 3: fetch the latest matching submission from the Unity API
// Priority 3: fetch the latest matching submission from the Unity API,
// falling back to seeding a fresh one via CHEFS if none currently
// match (e.g. every existing seeded submission has already been
// approved by a prior run) — so this spec is self-sufficient and
// doesn't depend on a separate seed step running first.
cy.fetchDynamicSubmission(TEST_CONFIG.fetchOptions).then((id) => {
submissionId = id;
cy.log(`✅ Fetched dynamic submission ID: ${submissionId}`);
if (id) {
submissionId = id;
cy.log(`✅ Fetched dynamic submission ID: ${submissionId}`);
return;
}

cy.log(
"⚠️ No matching submission found — seeding a fresh one via CHEFS",
);
cy.seedApprovalFlowSubmission().then((seededId) => {
submissionId = seededId;
cy.log(`✅ Seeded and using submission ID: ${submissionId}`);
});
});
},
);
Expand Down Expand Up @@ -619,6 +634,25 @@ const APPLICATIONS_PATH = "GrantApplications";
.enterSupplierNumber(TEST_CONFIG.supplierNumber)
.clickElsewhere()
.clickPaymentInfoSave();

// Saving the supplier number calls out to CAS to resolve it, which can
// transiently fail with "GetAuthTokenAsync: Error retrieving Token".
// When that happens the save silently doesn't attach a supplier, leaving
// SupplierId empty for the rest of the flow — dismiss and retry once.
cy.get("body").then(($body) => {
const hasTokenError =
$body.text().includes("GetAuthTokenAsync") ||
$body.text().includes("Error retrieving Token");

if (hasTokenError) {
cy.log("⚠️ Transient CAS token error on payment save — retrying once");
detailsPage.dismissErrorModalIfPresent();
detailsPage
.enterSupplierNumber(TEST_CONFIG.supplierNumber)
.clickElsewhere()
.clickPaymentInfoSave();
}
});
});

// Must use function() (not arrow) so this.skip() is accessible
Expand Down
42 changes: 26 additions & 16 deletions applications/Unity.AutoUI/cypress/scripts/chefs-api-config.json
Original file line number Diff line number Diff line change
@@ -1,21 +1,31 @@
{
"environments": {
"test": {
"baseURL": "https://chefs-test.apps.silver.devops.gov.bc.ca",
"formId": "46e25863-0ead-4aa8-897f-51e45f79e137",
"versionId": "4ef52ead-2cc3-4bdb-a7b7-73be983a7838"
},
"dev": {
"baseURL": "https://chefs-dev.apps.silver.devops.gov.bc.ca",
"formId": "233f47f9-b566-46c3-926a-73d565bf710f",
"versionId": "1e209d6b-46f5-4ddb-bc79-6e04033231cb"
},
"uat": {
"baseURL": "https://chefs-test.apps.silver.devops.gov.bc.ca",
"formId": "f2f45aa7-62c5-49ca-8846-b214e02adb46",
"versionId": "1d4d73ec-00e7-4b57-98c9-49d1e0c7d15b"
}
"environments": {
"dev": {
"baseURL": "https://chefs-dev.apps.silver.devops.gov.bc.ca",
"formId": "233f47f9-b566-46c3-926a-73d565bf710f",
"versionId": "1e209d6b-46f5-4ddb-bc79-6e04033231cb"
},
"dev2": {
"baseURL": "https://chefs-dev.apps.silver.devops.gov.bc.ca",
"formId": "92c0df4c-34f9-4a9a-a1b4-61c12495749c",
"versionId": "8218c285-7fa3-42df-b445-7e8ae835fad0"
},
"test": {
"baseURL": "https://chefs-test.apps.silver.devops.gov.bc.ca",
"formId": "46e25863-0ead-4aa8-897f-51e45f79e137",
"versionId": "4ef52ead-2cc3-4bdb-a7b7-73be983a7838"
},
"uat": {
"baseURL": "https://chefs-test.apps.silver.devops.gov.bc.ca",
"formId": "f2f45aa7-62c5-49ca-8846-b214e02adb46",
"versionId": "1d4d73ec-00e7-4b57-98c9-49d1e0c7d15b"
},
"prod": {
"baseURL": "https://submit.digital.gov.bc.ca",
"formId": "4defd3bf-f57c-4969-94a1-ced745a99ccf",
"versionId": "d8736cde-a11a-41be-8800-084f2dfcb825"
}
},
"headers": {
"Accept": "application/json",
"Content-Type": "application/json"
Expand Down
Loading
Loading