Skip to content
Merged

Dev #2007

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
21fb4b0
AB#31067: Show non-published form versions in the Parent Form dropdown
aurelio-aot Feb 2, 2026
f014cc2
Merge branch 'dev' into bugfix/AB#31067-non-published-version-not-sho…
aurelio-aot Feb 4, 2026
0beb507
AB#31067: Deduct paid/pending child amounts from parent amount
aurelio-aot Feb 5, 2026
56defc0
AB#31067: Form Hierarchy is no longer dependent to Application Form V…
aurelio-aot Feb 5, 2026
8790f74
AB#31066: Search Form Hierarchy Parent Form By Category
aurelio-aot Feb 5, 2026
ed795f1
AB#31067: Fix sonarqube issues
aurelio-aot Feb 5, 2026
9a8c806
AB#31067: Fix sonarqube issue
aurelio-aot Feb 5, 2026
35f2642
AB#30069: Change parent-child amount validation error message
aurelio-aot Feb 6, 2026
1c6e322
AB#30069: Group parent-child payment requests with a pink outline
aurelio-aot Feb 6, 2026
2657f80
AB#30069: Remove double outline for parent-child group
aurelio-aot Feb 6, 2026
599b46a
Merge branch 'dev' into bugfix/AB#31067-non-published-version-not-sho…
aurelio-aot Feb 6, 2026
6e8745a
AB#30069: Fix sonarqube issues
aurelio-aot Feb 6, 2026
41a2b1b
AB#30069: Change parent-child group outline color
aurelio-aot Feb 6, 2026
454bdef
AB#30069: Change parent-child group outline border tickness
aurelio-aot Feb 6, 2026
857ff9f
Secrets
JamesPasta Feb 12, 2026
2e538b2
Merge branch 'dev' into feature/AB#31672-AddTenantFields
JamesPasta Feb 12, 2026
7d582d1
AB#30069: Address copilot comment on unsanitized groupKey
aurelio-aot Feb 12, 2026
a526cc2
AB#3009: Address copilot comment on whitespace-only categories
aurelio-aot Feb 12, 2026
a0027e4
AB#30069: Address copilot comment on unsanitized IDs
aurelio-aot Feb 12, 2026
88450eb
AB#30069: Exclude self-reference when getting child links
aurelio-aot Feb 12, 2026
82c1d3b
Centralize authentication with cy.session() caching, reducing login t…
Feb 12, 2026
ea55354
feature/AB#31672-AddTenantFields
JamesPasta Feb 12, 2026
d43c6c9
Merge branch 'feature/AB#31672-AddTenantFields' of https://github.com…
JamesPasta Feb 12, 2026
85b3301
Update applications/Unity.AutoUI/cypress/e2e/ApplicationsActionBar.cy.ts
Stephan-McColm Feb 12, 2026
2d6ac6d
addressing code review comments
Feb 12, 2026
683f738
feature/AB#31672-AddTenantFields
JamesPasta Feb 12, 2026
1436bbb
Merge pull request #1991 from bcgov/feature/AB#31895-Cypress-Central-…
DarylTodosichuk Feb 12, 2026
c8c72c2
feature/AB#31672-AddTenantFields
JamesPasta Feb 12, 2026
cb4de54
feature/AB#31672-AddTenantFields-Sonar
JamesPasta Feb 12, 2026
9bb20c0
feature/AB#31672-AddTenantFields-Sonar
JamesPasta Feb 12, 2026
6194483
Merge branch 'dev' into feature/AB#31672-AddTenantFields
JamesPasta Feb 12, 2026
46ff608
feature/AB#31672-AddTenantFields-Sonar
JamesPasta Feb 12, 2026
e93a821
feature/AB#31672-AddTenantFields-Sonar
JamesPasta Feb 12, 2026
6cf918c
AB#31896 profile request services
AndreGAot Feb 12, 2026
459bf49
feature/AB#31672-AddTenantFields-Sonar
JamesPasta Feb 12, 2026
ba0ca64
feature/AB#31672-AddTenantFields-Sonar
JamesPasta Feb 13, 2026
47b22ab
AB#31896 sonarQ cleanup
AndreGAot Feb 13, 2026
cc7d88d
feature/AB#31826-New-IT-Statements-Applications-Actions-Bar - Added 2…
Stephan-McColm Feb 13, 2026
becee32
Merge pull request #1994 from bcgov/feature/AB#31826-New-IT-Statement…
DarylTodosichuk Feb 13, 2026
957b651
AB#31896 sonarQ
AndreGAot Feb 13, 2026
104e3f8
AB#31417: Display Started Operating Date in Applicant Profile
aurelio-aot Feb 13, 2026
7777b16
AB#31849: Remove Save View menu in Submissions Tab
aurelio-aot Feb 13, 2026
de698ab
AB#31896 OrgInfoDataProvider SQ
AndreGAot Feb 13, 2026
641316f
feature/AB#31672-AddTenantFields-FixKeys
JamesPasta Feb 13, 2026
0545343
feature/AB#31672-AddTenantFields-FixKeys
JamesPasta Feb 13, 2026
be6e8c0
Apply suggestions from code review
AndreGAot Feb 13, 2026
b28f9a8
AB#31896 remove profile key log
AndreGAot Feb 13, 2026
98bda8a
Merge pull request #1998 from bcgov/feature/AB#31896-applicant-profil…
AndreGAot Feb 13, 2026
6da7e30
Merge pull request #1990 from bcgov/feature/AB#31672-AddTenantFields
JamesPasta Feb 13, 2026
6d6df08
Merge pull request #1996 from bcgov/bugfix/AB#31849-No-Save-View-In-S…
JamesPasta Feb 13, 2026
a6ce5f8
feature/AB#31672-AddTenantFields-Sonar
JamesPasta Feb 13, 2026
25bde7f
Merge pull request #2003 from bcgov/feature/AB#31672-AddTenantFields
JamesPasta Feb 13, 2026
8472cc8
Merge pull request #1964 from bcgov/bugfix/AB#31067-non-published-ver…
JamesPasta Feb 13, 2026
43134ac
Merge pull request #1995 from bcgov/feature/AB#31417-Display-Applican…
JamesPasta Feb 13, 2026
d3f8890
bug/AB#31901-inverted-parent-child-links-in-display
DavidBrightBcGov Feb 13, 2026
3f8f470
Merge pull request #2006 from bcgov/bugfix/AB#31901-inverted-parent-c…
JamesPasta Feb 13, 2026
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
881 changes: 508 additions & 373 deletions applications/Unity.AutoUI/cypress/e2e/ApplicationsActionBar.cy.ts

Large diffs are not rendered by default.

705 changes: 376 additions & 329 deletions applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts

Large diffs are not rendered by default.

206 changes: 206 additions & 0 deletions applications/Unity.AutoUI/cypress/support/auth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
/**
* Authentication helper for Unity webapp
* Handles multiple authentication states and provides robust login flow
*/

interface LoginOptions {
baseUrl?: string;
useMfa?: boolean;
timeout?: number;
username?: string;
password?: string;
}

/**
* Detects if we're on the Keycloak login provider selection page
*/
function isKeycloakPage($body: JQuery<HTMLElement>): boolean {
return (
$body.find(".login-pf-page").length > 0 ||
$body.find("#social-idir").length > 0 ||
$body.find("#social-azureidir").length > 0
);
}

/**
* Detects if we're already logged in
*/
function isLoggedIn($body: JQuery<HTMLElement>): boolean {
return (
$body.find('button:contains("VIEW APPLICATIONS")').length > 0 ||
$body.find("#GrantApplicationsTable").length > 0
);
}

/**
* Detects if we're on the login landing page
*/
function isLoginPage($body: JQuery<HTMLElement>): boolean {
return $body.find('button:contains("LOGIN")').length > 0;
}

/**
* Handles the Keycloak IDIR selection and login form
*/
function handleKeycloakLogin(
options: LoginOptions,
useMfa: boolean,
timeout: number,
): void {
cy.log("🔑 Handling Keycloak login flow");

cy.get("body", { timeout }).then(($body) => {
// Click appropriate IDIR provider
if (useMfa && $body.find("#social-azureidir").length > 0) {
cy.log("Selecting IDIR - MFA");
cy.get("#social-azureidir", { timeout }).should("be.visible").click();
} else if ($body.find("#social-idir").length > 0) {
cy.log("Selecting IDIR");
cy.get("#social-idir", { timeout }).should("be.visible").click();
} else {
throw new Error(
"Expected Keycloak IDIR provider buttons but none found. Available: " +
$body
.find("a[id^='social-']")
.map((_, el) => el.id)
.get()
.join(", "),
);
}
});

// Handle username/password form if it appears
cy.get("body", { timeout }).then(($loginBody) => {
if ($loginBody.find("#user").length > 0) {
cy.log("Entering IDIR credentials");

const username = options.username || Cypress.env("test1username");
const password = options.password || Cypress.env("test1password");

cy.get("#user", { timeout })
.should("be.visible")
.type(username, { log: false });

cy.get("#password", { timeout })
.should("be.visible")
.type(password, { log: false });

// Look for Continue button or submit the form
cy.get("body").then(($formBody) => {
if ($formBody.find('button:contains("Continue")').length > 0) {
cy.contains("button", "Continue", { timeout }).click();
} else if ($formBody.find("input[type='submit']").length > 0) {
cy.get("input[type='submit']", { timeout }).click();
} else {
cy.log("⚠️ No submit button found, attempting form submission");
cy.get("#user").parents("form").submit();
}
});
} else {
cy.log("✓ Already authenticated, skipping credentials");
}
});
}

/**
* Ensures we end up at the GrantApplications page
*/
function ensureGrantApplicationsPage(timeout: number): void {
cy.location("pathname", { timeout }).then((pathname) => {
if (pathname.includes("/GrantApplications")) {
cy.log("✓ Already at GrantApplications page");
return;
}

// Check if VIEW APPLICATIONS button exists
cy.get("body", { timeout }).then(($body) => {
if ($body.find('button:contains("VIEW APPLICATIONS")').length > 0) {
cy.log("Clicking VIEW APPLICATIONS button");
cy.contains("button", "VIEW APPLICATIONS", { timeout })
.should("be.visible")
.click();
}
});
});

// Final assertion - we should be at GrantApplications
cy.location("pathname", { timeout }).should("include", "/GrantApplications");
cy.log("✓ Successfully navigated to GrantApplications");
}

/**
* Performs the actual login flow
*/
function performLogin(options: LoginOptions = {}): void {
const baseUrl = options.baseUrl || (Cypress.env("webapp.url") as string);
const useMfa = options.useMfa || false;
const timeout = options.timeout || 20000;

cy.visit(baseUrl);

cy.get("body", { timeout }).then(($body) => {
// Check if already logged in
if (isLoggedIn($body)) {
cy.log("✓ Already logged in");
return;
}

// Click LOGIN button if on landing page
if (isLoginPage($body)) {
cy.log("Clicking LOGIN button");
cy.contains("button", "LOGIN", { timeout }).click();
}
});

// Handle Keycloak login if needed
cy.get("body", { timeout }).then(($body) => {
if (isKeycloakPage($body)) {
handleKeycloakLogin(options, useMfa, timeout);
}
});

// Wait for login to complete - verify we're at GrantApplications or can navigate there
ensureGrantApplicationsPage(timeout);
}

/**
* Robust login helper that handles multiple Unity webapp states
*
* @example
* // In your test
* import { loginIfNeeded } from "../support/auth";
*
* beforeEach(() => {
* loginIfNeeded();
* });
*/
export function loginIfNeeded(
options: LoginOptions = {},
): Cypress.Chainable<void> {
const username = options.username || (Cypress.env("test1username") as string);
const baseUrl = options.baseUrl || (Cypress.env("webapp.url") as string);
const sessionId = `unity-${baseUrl}-${username}`;

return cy
.session(
sessionId,
() => {
performLogin(options);
},
{
validate() {
// Lightweight validation: check auth cookies exist without visiting
return cy.getCookie(".AspNetCore.Cookies").then((cookie) => {
if (!cookie) {
throw new Error("Session expired - auth cookie missing");
}
});
},
cacheAcrossSpecs: true,
},
)
.then(() => {
cy.visit(baseUrl);
ensureGrantApplicationsPage(options.timeout || 20000);
});
}
Loading
Loading