Skip to content
Merged

Dev #2258

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
047e03e
AB#32465 Refactor AI endpoint configuration management
jacobwillsmith Apr 8, 2026
3b1f28c
AB#32465 Update AI development configuration template
jacobwillsmith Apr 8, 2026
df9bb32
fix applicationbar cypress test
Apr 9, 2026
3ac2dea
AB#32491 address updates from portal
AndreGAot Apr 9, 2026
08b480f
AB#32491 sonarQube cleanup
AndreGAot Apr 10, 2026
42fb95d
AB#32465 fix sonar issues in endpoint path join
jacobwillsmith Apr 10, 2026
a5cbab8
feature/AB#32612 - hardening lists.cy.ts to account for slow report l…
Stephan-McColm Apr 10, 2026
dedecd3
AB#32491 abstract appropriate base classes and refactor cognitive com…
AndreGAot Apr 10, 2026
8a30230
AB#32613 Remove SonarCloud scans from PRs
DarylTodosichuk Apr 10, 2026
143e794
Merge pull request #2254 from bcgov/feature/AB#32613-SonarQube-GitHub…
DarylTodosichuk Apr 10, 2026
a67072b
Merge pull request #2251 from bcgov/feature/AB#32612-FixCypressApplic…
DarylTodosichuk Apr 10, 2026
dbbe6fa
Merge pull request #2242 from bcgov/feature/AB#32465-model-endpoint-c…
jacobwillsmith Apr 10, 2026
1edc72d
AB#32491 copilot suggestions
AndreGAot Apr 10, 2026
2d00449
Merge pull request #2252 from bcgov/feature/AB#32491-portal-address-u…
AndreGAot Apr 10, 2026
e958f5e
bugfix/AB#32600-FixFilterAsterix
JamesPasta Apr 10, 2026
284cfa7
Merge pull request #2256 from bcgov/bugfix/AB#32600-FixFilterAsterix
JamesPasta Apr 10, 2026
cf32934
bugfix/AB#31304-HideTinyButtonPanelonScroll
JamesPasta Apr 10, 2026
f1406aa
Merge pull request #2257 from bcgov/bugfix/AB#32600-FixFilterAsterix
JamesPasta Apr 10, 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
6 changes: 3 additions & 3 deletions .github/workflows/sonarsource-scan.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ on:
# - dev
# - test
# - main
pull_request:
types: [opened, synchronize, reopened]
workflow_dispatch:
# pull_request:
# types: [opened, synchronize, reopened]
# workflow_dispatch:

permissions:
contents: read
Expand Down
81 changes: 36 additions & 45 deletions applications/Unity.AutoUI/cypress/e2e/lists.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,48 +57,37 @@ describe('Grant Manager Login and List Navigation', () => {
const listboxSel = '#bs-select-1[role="listbox"]'
const searchSel = 'input[type="search"][aria-controls="bs-select-1"]'

cy.get('body').then(($body) => {
if ($body.find(btnSel).length === 0) {
cy.log('Skipping intake switch: selector not found')
return
}
cy.get(btnSel, { timeout: 30000 })
.should('be.visible')
.first()
.click({ force: true })

cy.get(btnSel).first().click({ force: true })
cy.get(listboxSel, { timeout: 20000 }).should('exist')
cy.get(listboxSel, { timeout: 30000 }).should('be.visible')

cy.get('body').then(($b2) => {
if ($b2.find(searchSel).length > 0) {
cy.get(searchSel).clear().type('Test')
}
})
cy.get(searchSel, { timeout: 30000 })
.should('be.visible')
.clear()
.type('Test')

cy.get(listboxSel).within(() => {
cy.get('a.dropdown-item[role="option"]').then(($opts) => {
const match = $opts.filter((_, el) => {
const textNode = el.querySelector('span.text')
const text = textNode ? textNode.textContent || '' : ''
return text.trim() === 'Test'
})
cy.contains(`${listboxSel} a.dropdown-item[role="option"] span.text`, /^Test$/, { timeout: 30000 })
.closest('a.dropdown-item')
.then(($opt) => {
const selected =
$opt.attr('aria-selected') === 'true' ||
$opt.hasClass('selected')

if (match.length === 0) {
cy.log('Skipping intake switch: Test not found')
return
}

const el = match.get(0)
const selected =
el.getAttribute('aria-selected') === 'true' ||
el.classList.contains('selected')

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

cy.get(btnSel).first().click({ force: true })
cy.get(btnSel).first().should('have.attr', 'aria-expanded', 'false')
cy.get('select#dashboardIntakeId option:selected').should(($opts) => {
const texts = Array.from($opts, (opt) => (opt.textContent || '').trim())
expect(texts).to.include('Test')
})

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

it('Verify Login', () => {
Expand Down Expand Up @@ -160,33 +149,35 @@ describe('Grant Manager Login and List Navigation', () => {
cy.get('#user-dropdown .btn-dropdown span')
.should('contain', 'Default Grants Program')

cy.contains("Applications").click()
cy.contains('Applications').click()
cy.get('tbody tr').should('have.length.at.least', 1)

cy.contains("Roles").click()
cy.contains('Roles').click()
cy.get('tbody tr').should('have.length.at.least', 1)

cy.contains("Users").click()
cy.contains('Users').click()
cy.get('tbody tr').should('have.length.at.least', 1)

cy.contains("Intakes").click()
cy.contains('Intakes').click()
cy.get('tbody tr').should('have.length.at.least', 1)

cy.contains("Forms").click()
cy.contains('Forms').click()
cy.get('tbody tr').should('have.length.at.least', 1)

cy.contains("Dashboard").click()
cy.contains('Dashboard').click()
cy.location('pathname', { timeout: 30000 }).should('include', '/Dashboard')
setDashboardIntakeToTestIfAvailable()

cy.get('#applicationStatusChart text')
cy.get('#applicationStatusChart text', { timeout: 30000 })
.first()
.invoke('text')
.then(n => expect(parseInt(n, 10)).to.be.gt(0))
.should(($el) => {
expect(parseInt($el.text(), 10)).to.be.gt(0)
})

cy.visit(Cypress.env('webapp.url'))
})

it('Verify Logout', () => {
cy.logout()
})
})
})
100 changes: 58 additions & 42 deletions applications/Unity.AutoUI/cypress/pages/ApplicationsListPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ export class ApplicationsListPage extends ApplicationsPage {
private readonly extendedActionBar = {
customButtons: "#app_custom_buttons",
dynamicButtonContainer: "#dynamicButtonContainerId",
exportButton: "#dynamicButtonContainerId .dt-buttons button span",
// Export can be rendered as button/span or anchor depending on DataTables build.
exportButton:
"#dynamicButtonContainerId .dt-buttons button, #dynamicButtonContainerId .dt-buttons a, #dynamicButtonContainerId .dt-buttons span",
saveViewButton: "button.grp-savedStates",
};

Expand Down Expand Up @@ -94,7 +96,7 @@ export class ApplicationsListPage extends ApplicationsPage {
| "last3months"
| "last6months"
| "alltime"
| "custom"
| "custom",
): this {
cy.get(this.dateFilters.quickDateRange, { timeout: this.STANDARD_TIMEOUT })
.should("be.visible")
Expand Down Expand Up @@ -127,10 +129,11 @@ export class ApplicationsListPage extends ApplicationsPage {
| "last3months"
| "last6months"
| "alltime"
| "custom"
| "custom",
): this {
cy.get(this.dateFilters.quickDateRange, { timeout: this.STANDARD_TIMEOUT })
.should("have.value", expectedValue);
cy.get(this.dateFilters.quickDateRange, {
timeout: this.STANDARD_TIMEOUT,
}).should("have.value", expectedValue);
return this;
}

Expand All @@ -139,7 +142,9 @@ export class ApplicationsListPage extends ApplicationsPage {
* @deprecated Use selectQuickDateRange() instead. This method is for custom date ranges only.
*/
setSubmittedFromDate(date: string): this {
cy.get(this.dateFilters.submittedFromDate, { timeout: this.STANDARD_TIMEOUT })
cy.get(this.dateFilters.submittedFromDate, {
timeout: this.STANDARD_TIMEOUT,
})
.click({ force: true })
.clear({ force: true })
.type(date, { force: true })
Expand Down Expand Up @@ -172,7 +177,7 @@ export class ApplicationsListPage extends ApplicationsPage {
cy.wrap($s)
.should("have.attr", "style")
.and("contain", "display: none");
}
},
);
return this;
}
Expand Down Expand Up @@ -225,10 +230,9 @@ export class ApplicationsListPage extends ApplicationsPage {
* Verify table has rows (using scroll body selector)
*/
verifyTableHasData(): this {
cy.get(this.scrollTable.tableRows, { timeout: this.STANDARD_TIMEOUT }).should(
"have.length.greaterThan",
1
);
cy.get(this.scrollTable.tableRows, {
timeout: this.STANDARD_TIMEOUT,
}).should("have.length.greaterThan", 1);
return this;
}

Expand Down Expand Up @@ -274,7 +278,9 @@ export class ApplicationsListPage extends ApplicationsPage {
.then(($els: JQuery<HTMLElement>) => {
const titles: string[] = Cypress.$($els)
.toArray()
.map((el: HTMLElement) => (el.textContent || "").replace(/\s+/g, " ").trim())
.map((el: HTMLElement) =>
(el.textContent || "").replace(/\s+/g, " ").trim(),
)
.filter((t: string) => t.length > 0);
return titles;
});
Expand All @@ -287,10 +293,9 @@ export class ApplicationsListPage extends ApplicationsPage {
this.getVisibleHeaderTitles().then((titles: string[]) => {
const titlesLower = titles.map((t: string) => t.toLowerCase());
expected.forEach((e: string) => {
expect(
titlesLower,
`visible headers should include "${e}"`
).to.include(e.toLowerCase());
expect(titlesLower, `visible headers should include "${e}"`).to.include(
e.toLowerCase(),
);
});
});
return this;
Expand All @@ -302,7 +307,9 @@ export class ApplicationsListPage extends ApplicationsPage {
* Scroll to and verify action bar exists
*/
verifyActionBarExists(): this {
cy.get(this.extendedActionBar.customButtons, { timeout: this.STANDARD_TIMEOUT })
cy.get(this.extendedActionBar.customButtons, {
timeout: this.STANDARD_TIMEOUT,
})
.should("exist")
.scrollIntoView();
return this;
Expand All @@ -325,6 +332,7 @@ export class ApplicationsListPage extends ApplicationsPage {
verifyExportButtonVisible(): this {
cy.contains(this.extendedActionBar.exportButton, "Export", {
timeout: this.STANDARD_TIMEOUT,
matchCase: false,
}).should("be.visible");
return this;
}
Expand All @@ -336,7 +344,7 @@ export class ApplicationsListPage extends ApplicationsPage {
cy.contains(
"#dynamicButtonContainerId button.grp-savedStates",
"Save View",
{ timeout: this.STANDARD_TIMEOUT }
{ timeout: this.STANDARD_TIMEOUT },
).should("be.visible");
return this;
}
Expand All @@ -346,9 +354,9 @@ export class ApplicationsListPage extends ApplicationsPage {
*/
verifyColumnsButtonVisible(): this {
cy.contains(
"#dynamicButtonContainerId .dt-buttons button span",
"#dynamicButtonContainerId .dt-buttons button, #dynamicButtonContainerId .dt-buttons a, #dynamicButtonContainerId .dt-buttons span",
"Columns",
{ timeout: this.STANDARD_TIMEOUT }
{ timeout: this.STANDARD_TIMEOUT },
).should("be.visible");
return this;
}
Expand Down Expand Up @@ -393,9 +401,11 @@ export class ApplicationsListPage extends ApplicationsPage {

// Try Cancel button if available (check existence first to avoid timeout)
cy.get("body").then(($body: JQuery<HTMLBodyElement>) => {
const $cancelBtn = $body.find(this.paymentModal.cancelButton).filter(
(_: number, el: HTMLElement) => (el.textContent || "").includes("Cancel")
);
const $cancelBtn = $body
.find(this.paymentModal.cancelButton)
.filter((_: number, el: HTMLElement) =>
(el.textContent || "").includes("Cancel"),
);
if ($cancelBtn.length > 0) {
cy.wrap($cancelBtn.first()).scrollIntoView().click({ force: true });
} else {
Expand Down Expand Up @@ -441,11 +451,11 @@ export class ApplicationsListPage extends ApplicationsPage {
($m: JQuery<HTMLElement>) => {
const isHidden = !$m.is(":visible") || !$m.hasClass("show");
expect(isHidden, "payment-modal hidden or not shown").to.eq(true);
}
);
cy.get(this.paymentModal.backdrop, { timeout: this.STANDARD_TIMEOUT }).should(
"not.exist"
},
);
cy.get(this.paymentModal.backdrop, {
timeout: this.STANDARD_TIMEOUT,
}).should("not.exist");
return this;
}

Expand Down Expand Up @@ -479,26 +489,28 @@ export class ApplicationsListPage extends ApplicationsPage {
.click({ force: true });

// Wait for table to rebuild
cy.get(this.scrollTable.columnTitles, { timeout: this.STANDARD_TIMEOUT }).should(
"have.length.gt",
5
);
cy.get(this.scrollTable.columnTitles, {
timeout: this.STANDARD_TIMEOUT,
}).should("have.length.gt", 5);
return this;
}

/**
* Open the Columns menu
*/
openColumnsMenu(): this {
cy.contains("span", "Columns", { timeout: this.STANDARD_TIMEOUT })
cy.contains(
"#dynamicButtonContainerId .dt-buttons button, #dynamicButtonContainerId .dt-buttons a, #dynamicButtonContainerId .dt-buttons span",
/^Columns$/i,
{ timeout: this.STANDARD_TIMEOUT },
)
.should("be.visible")
.click();

// Wait for dropdown to be fully populated
cy.get(this.columnsMenu.dropdownItem, { timeout: this.STANDARD_TIMEOUT }).should(
"have.length.gt",
50
);
cy.get(this.columnsMenu.dropdownItem, {
timeout: this.STANDARD_TIMEOUT,
}).should("have.length.gt", 50);
return this;
}

Expand Down Expand Up @@ -530,7 +542,9 @@ export class ApplicationsListPage extends ApplicationsPage {
* Close the Columns menu
*/
closeColumnsMenu(): this {
cy.get(this.columnsMenu.buttonBackground, { timeout: this.STANDARD_TIMEOUT })
cy.get(this.columnsMenu.buttonBackground, {
timeout: this.STANDARD_TIMEOUT,
})
.should("exist")
.click({ force: true });

Expand Down Expand Up @@ -567,7 +581,7 @@ export class ApplicationsListPage extends ApplicationsPage {

if (switchLink.length === 0) {
cy.log(
'Skipping tenant switch: "Switch Grant Programs" not present for this user/session'
'Skipping tenant switch: "Switch Grant Programs" not present for this user/session',
);
cy.get("body").click(0, 0);
return;
Expand All @@ -577,10 +591,12 @@ export class ApplicationsListPage extends ApplicationsPage {

cy.url({ timeout: this.STANDARD_TIMEOUT }).should(
"include",
"/GrantPrograms"
"/GrantPrograms",
);

cy.get(this.grantProgram.searchInput, { timeout: this.STANDARD_TIMEOUT })
cy.get(this.grantProgram.searchInput, {
timeout: this.STANDARD_TIMEOUT,
})
.should("be.visible")
.clear()
.type(programName);
Expand All @@ -596,9 +612,9 @@ export class ApplicationsListPage extends ApplicationsPage {
cy.location("pathname", { timeout: this.STANDARD_TIMEOUT }).should(
(p: string) => {
expect(
p.indexOf("/GrantApplications") >= 0 || p.indexOf("/auth/") >= 0
p.indexOf("/GrantApplications") >= 0 || p.indexOf("/auth/") >= 0,
).to.eq(true);
}
},
);
});
});
Expand Down
Loading
Loading